@keboola/design 16.1.0 → 17.1.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 (190) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/dist/{AIKit-Cf5plya2.js → AIKit-DyysN1kS.js} +35 -45
  3. package/dist/AIKit-DyysN1kS.js.map +1 -0
  4. package/dist/{Alert-DziS8n1H.js → Alert-BQB-og_I.js} +2 -2
  5. package/dist/{Alert-DziS8n1H.js.map → Alert-BQB-og_I.js.map} +1 -1
  6. package/dist/{AlertModal-De04fFoy.js → AlertModal-BkmyEvsR.js} +2 -2
  7. package/dist/{AlertModal-De04fFoy.js.map → AlertModal-BkmyEvsR.js.map} +1 -1
  8. package/dist/{AppShell-BUa3U7-e.js → AppShell-CDbecT-t.js} +2 -2
  9. package/dist/{AppShell-BUa3U7-e.js.map → AppShell-CDbecT-t.js.map} +1 -1
  10. package/dist/{BrandEditor-hiLBX7az.js → BrandEditor-BHE6nsob.js} +6 -6
  11. package/dist/{BrandEditor-hiLBX7az.js.map → BrandEditor-BHE6nsob.js.map} +1 -1
  12. package/dist/{BrandLogo-Dn7hhp2c.js → BrandLogo-n4Qhi1tI.js} +2 -2
  13. package/dist/{BrandLogo-Dn7hhp2c.js.map → BrandLogo-n4Qhi1tI.js.map} +1 -1
  14. package/dist/{Breadcrumb-uGFEIjFF.js → Breadcrumb-BAwQTo0c.js} +3 -3
  15. package/dist/{Breadcrumb-uGFEIjFF.js.map → Breadcrumb-BAwQTo0c.js.map} +1 -1
  16. package/dist/{Button-DbvGzEDb.js → Button-BAMX1iuI.js} +2 -2
  17. package/dist/{Button-DbvGzEDb.js.map → Button-BAMX1iuI.js.map} +1 -1
  18. package/dist/{Checkbox-B2jLlyaO.js → Checkbox-CfjpwIcg.js} +2 -2
  19. package/dist/{Checkbox-B2jLlyaO.js.map → Checkbox-CfjpwIcg.js.map} +1 -1
  20. package/dist/{Clipboard-fAkDdpEu.js → Clipboard-BaU3cDi5.js} +7 -5
  21. package/dist/Clipboard-BaU3cDi5.js.map +1 -0
  22. package/dist/{ClipboardButton-71Ugbl8c.js → ClipboardButton-BWeaQEM2.js} +5 -4
  23. package/dist/ClipboardButton-BWeaQEM2.js.map +1 -0
  24. package/dist/{CodeEditor-D_b-ZCng.js → CodeEditor-BdTxkPD4.js} +4 -4
  25. package/dist/{CodeEditor-D_b-ZCng.js.map → CodeEditor-BdTxkPD4.js.map} +1 -1
  26. package/dist/{ColorInput-Cjr1jkvy.js → ColorInput-BoVdBxJ7.js} +3 -3
  27. package/dist/{ColorInput-Cjr1jkvy.js.map → ColorInput-BoVdBxJ7.js.map} +1 -1
  28. package/dist/{ColorModeSwitch-CuPYnJ2V.js → ColorModeSwitch-BDkdmHYl.js} +2 -2
  29. package/dist/{ColorModeSwitch-CuPYnJ2V.js.map → ColorModeSwitch-BDkdmHYl.js.map} +1 -1
  30. package/dist/{Combobox-DYjvYgl3.js → Combobox-RZ0i3w8u.js} +4 -4
  31. package/dist/{Combobox-DYjvYgl3.js.map → Combobox-RZ0i3w8u.js.map} +1 -1
  32. package/dist/{Command-BcTb6GsR.js → Command-D6XYzzJf.js} +2 -2
  33. package/dist/{Command-BcTb6GsR.js.map → Command-D6XYzzJf.js.map} +1 -1
  34. package/dist/{CopyField-CnwAvQz9.js → CopyField-9WBU8thS.js} +2 -2
  35. package/dist/{CopyField-CnwAvQz9.js.map → CopyField-9WBU8thS.js.map} +1 -1
  36. package/dist/{DateInput-DJNX7Vdx.js → DateInput-CCYG0AtT.js} +3 -3
  37. package/dist/{DateInput-DJNX7Vdx.js.map → DateInput-CCYG0AtT.js.map} +1 -1
  38. package/dist/{DateRangeInput-B3g8cyS0.js → DateRangeInput-CpZK1IFp.js} +3 -3
  39. package/dist/{DateRangeInput-B3g8cyS0.js.map → DateRangeInput-CpZK1IFp.js.map} +1 -1
  40. package/dist/{DateRangePicker-48yOB2qV.js → DateRangePicker-B2AUKX7u.js} +2 -2
  41. package/dist/{DateRangePicker-48yOB2qV.js.map → DateRangePicker-B2AUKX7u.js.map} +1 -1
  42. package/dist/{FieldItem-D7eCMfMB.js → FieldItem-eM7IHBt5.js} +3 -3
  43. package/dist/{FieldItem-D7eCMfMB.js.map → FieldItem-eM7IHBt5.js.map} +1 -1
  44. package/dist/{FileUpload-DskvxhAr.js → FileUpload-d-hNPfPV.js} +2 -2
  45. package/dist/{FileUpload-DskvxhAr.js.map → FileUpload-d-hNPfPV.js.map} +1 -1
  46. package/dist/{Form-BUNW7nlt.js → Form-B_9sNehB.js} +7 -7
  47. package/dist/{Form-BUNW7nlt.js.map → Form-B_9sNehB.js.map} +1 -1
  48. package/dist/{FormGroup-QJB21LKp.js → FormGroup-D7ahkK1q.js} +3 -3
  49. package/dist/{FormGroup-QJB21LKp.js.map → FormGroup-D7ahkK1q.js.map} +1 -1
  50. package/dist/{FullScreenModal-RzY5XxiG.js → FullScreenModal-CiRKNsls.js} +2 -2
  51. package/dist/{FullScreenModal-RzY5XxiG.js.map → FullScreenModal-CiRKNsls.js.map} +1 -1
  52. package/dist/{InlineEdit-CXL0ZslO.js → InlineEdit-BzOox46S.js} +4 -4
  53. package/dist/{InlineEdit-CXL0ZslO.js.map → InlineEdit-BzOox46S.js.map} +1 -1
  54. package/dist/{InputGroup-BWeanEo7.js → InputGroup-DnGP9-ZQ.js} +2 -2
  55. package/dist/{InputGroup-BWeanEo7.js.map → InputGroup-DnGP9-ZQ.js.map} +1 -1
  56. package/dist/{Kbd-BprYCICe.js → Kbd-6velz9J-.js} +2 -2
  57. package/dist/{Kbd-BprYCICe.js.map → Kbd-6velz9J-.js.map} +1 -1
  58. package/dist/{MermaidDiagram-E3azndPk.js → MermaidDiagram-l83gco3r.js} +2 -2
  59. package/dist/{MermaidDiagram-E3azndPk.js.map → MermaidDiagram-l83gco3r.js.map} +1 -1
  60. package/dist/{Modal-Cf_kPEBW.js → Modal-CLu6Eg5p.js} +2 -2
  61. package/dist/{Modal-Cf_kPEBW.js.map → Modal-CLu6Eg5p.js.map} +1 -1
  62. package/dist/{MultiActionButtonGroup-8WQwL4UQ.js → MultiActionButtonGroup-B3-wNw7w.js} +3 -3
  63. package/dist/{MultiActionButtonGroup-8WQwL4UQ.js.map → MultiActionButtonGroup-B3-wNw7w.js.map} +1 -1
  64. package/dist/{Navbar-CRjxVboE.js → Navbar-BEc-Pqo5.js} +2 -2
  65. package/dist/{Navbar-CRjxVboE.js.map → Navbar-BEc-Pqo5.js.map} +1 -1
  66. package/dist/{PageLayout-LcvJccOW.js → PageLayout-kY31oUix.js} +2 -2
  67. package/dist/{PageLayout-LcvJccOW.js.map → PageLayout-kY31oUix.js.map} +1 -1
  68. package/dist/{PageToolbar-By2HznxO.js → PageToolbar-NmiausP7.js} +2 -2
  69. package/dist/{PageToolbar-By2HznxO.js.map → PageToolbar-NmiausP7.js.map} +1 -1
  70. package/dist/{Pagination-DrXTrvfD.js → Pagination-DidOPSPB.js} +2 -2
  71. package/dist/{Pagination-DrXTrvfD.js.map → Pagination-DidOPSPB.js.map} +1 -1
  72. package/dist/{Popconfirm-BJuDOHdv.js → Popconfirm-C4ryoeGP.js} +2 -2
  73. package/dist/{Popconfirm-BJuDOHdv.js.map → Popconfirm-C4ryoeGP.js.map} +1 -1
  74. package/dist/{RadioGroup-B9oC8P15.js → RadioGroup-BIElT-nH.js} +2 -2
  75. package/dist/{RadioGroup-B9oC8P15.js.map → RadioGroup-BIElT-nH.js.map} +1 -1
  76. package/dist/{Search-OgaNjqQM.js → Search-xDWaQ2z3.js} +2 -2
  77. package/dist/{Search-OgaNjqQM.js.map → Search-xDWaQ2z3.js.map} +1 -1
  78. package/dist/{SearchInput-eLS-uvOn.js → SearchInput-BwlJ77mV.js} +3 -3
  79. package/dist/{SearchInput-eLS-uvOn.js.map → SearchInput-BwlJ77mV.js.map} +1 -1
  80. package/dist/{SectionNav-L81iJBo3.js → SectionNav-DV3Hwj-5.js} +14 -8
  81. package/dist/SectionNav-DV3Hwj-5.js.map +1 -0
  82. package/dist/{Select-DRdkdzBp.js → Select-C3Q_Xk_Z.js} +2 -2
  83. package/dist/{Select-DRdkdzBp.js.map → Select-C3Q_Xk_Z.js.map} +1 -1
  84. package/dist/{Sheet-DVb4XoJ5.js → Sheet-D7NnOyud.js} +2 -2
  85. package/dist/{Sheet-DVb4XoJ5.js.map → Sheet-D7NnOyud.js.map} +1 -1
  86. package/dist/{Sidebar-DYvodJWN.js → Sidebar-DaUDM8jm.js} +5 -5
  87. package/dist/{Sidebar-DYvodJWN.js.map → Sidebar-DaUDM8jm.js.map} +1 -1
  88. package/dist/{Slider-B9IskDxf.js → Slider-Cdl8FOvI.js} +3 -3
  89. package/dist/{Slider-B9IskDxf.js.map → Slider-Cdl8FOvI.js.map} +1 -1
  90. package/dist/{Table-BwgBm3hJ.js → Table-DtLrXt4i.js} +39 -7
  91. package/dist/Table-DtLrXt4i.js.map +1 -0
  92. package/dist/{Tabs-DmJB4l_N.js → Tabs-DUOUQKh7.js} +2 -2
  93. package/dist/{Tabs-DmJB4l_N.js.map → Tabs-DUOUQKh7.js.map} +1 -1
  94. package/dist/{TextInput--1CfZybC.js → TextInput-BAL-zOAN.js} +3 -3
  95. package/dist/{TextInput--1CfZybC.js.map → TextInput-BAL-zOAN.js.map} +1 -1
  96. package/dist/{ThemeProvider-BCHllN7d.js → ThemeProvider-MzVbTDBj.js} +2 -2
  97. package/dist/{ThemeProvider-BCHllN7d.js.map → ThemeProvider-MzVbTDBj.js.map} +1 -1
  98. package/dist/{ToggleAllTooltip-BFmA6TXf.js → ToggleAllTooltip-DQE5Lw6w.js} +2 -2
  99. package/dist/{ToggleAllTooltip-BFmA6TXf.js.map → ToggleAllTooltip-DQE5Lw6w.js.map} +1 -1
  100. package/dist/{ZoomableSvg-BRPGgaWJ.js → ZoomableSvg-CIOqAYpd.js} +4 -4
  101. package/dist/{ZoomableSvg-BRPGgaWJ.js.map → ZoomableSvg-CIOqAYpd.js.map} +1 -1
  102. package/dist/editors.js +3 -3
  103. package/dist/flint.js +1 -1
  104. package/dist/index.d.ts +409 -365
  105. package/dist/index.js +52 -50
  106. package/dist/internal/blocks/AIKit.js +1 -1
  107. package/dist/internal/blocks/AppShell.js +1 -1
  108. package/dist/internal/blocks/AuthLayout.js +1 -1
  109. package/dist/internal/blocks/BrandEditor.js +1 -1
  110. package/dist/internal/blocks/BulkActionsBar.js +55 -0
  111. package/dist/internal/blocks/BulkActionsBar.js.map +1 -0
  112. package/dist/internal/blocks/ChipEditor.js +2 -2
  113. package/dist/internal/blocks/ClipboardButton.js +1 -1
  114. package/dist/internal/blocks/ColorInput.js +1 -1
  115. package/dist/internal/blocks/ColorModeSwitch.js +1 -1
  116. package/dist/internal/blocks/Command.js +1 -1
  117. package/dist/internal/blocks/CopyField.js +1 -1
  118. package/dist/internal/blocks/DateInput.js +1 -1
  119. package/dist/internal/blocks/DateRangeInput.js +1 -1
  120. package/dist/internal/blocks/EmptyState.js +7 -2
  121. package/dist/internal/blocks/EmptyState.js.map +1 -1
  122. package/dist/internal/blocks/ExportMenu.js +2 -2
  123. package/dist/internal/blocks/Form/connectors/ComboboxField.js +2 -2
  124. package/dist/internal/blocks/Form/connectors/MultiComboboxField.js +1 -1
  125. package/dist/internal/blocks/Form.js +2 -2
  126. package/dist/internal/blocks/FormGroup.js +1 -1
  127. package/dist/internal/blocks/InlineEdit.js +1 -1
  128. package/dist/internal/blocks/MultiActionButtonGroup.js +1 -1
  129. package/dist/internal/blocks/MultiCombobox.js +3 -3
  130. package/dist/internal/blocks/NumberInput.js +1 -1
  131. package/dist/internal/blocks/PageLayout.js +1 -1
  132. package/dist/internal/blocks/PageSection.js +31 -0
  133. package/dist/internal/blocks/PageSection.js.map +1 -0
  134. package/dist/internal/blocks/PageToolbar.js +1 -1
  135. package/dist/internal/blocks/PasswordInput.js +2 -2
  136. package/dist/internal/blocks/SearchInput.js +1 -1
  137. package/dist/internal/blocks/SearchInputWithNavigation.js +3 -3
  138. package/dist/internal/blocks/SectionNav.js +1 -1
  139. package/dist/internal/blocks/SplitButton.js +1 -1
  140. package/dist/internal/blocks/TextInput.js +1 -1
  141. package/dist/internal/blocks/Textarea.js +1 -1
  142. package/dist/internal/blocks/TimeInput.js +2 -2
  143. package/dist/internal/components/Alert.js +1 -1
  144. package/dist/internal/components/AlertModal.js +1 -1
  145. package/dist/internal/components/Avatar.js +1 -1
  146. package/dist/internal/components/BrandLogo.js +1 -1
  147. package/dist/internal/components/Breadcrumb.js +1 -1
  148. package/dist/internal/components/Button.js +1 -1
  149. package/dist/internal/components/Checkbox.js +1 -1
  150. package/dist/internal/components/Clipboard.js +1 -1
  151. package/dist/internal/components/CollapsiblePanel.js +1 -1
  152. package/dist/internal/components/Combobox.js +1 -1
  153. package/dist/internal/components/DateRangePicker.js +1 -1
  154. package/dist/internal/components/FileUpload.js +1 -1
  155. package/dist/internal/components/FullScreenModal.js +1 -1
  156. package/dist/internal/components/InputGroup.js +1 -1
  157. package/dist/internal/components/Kbd.js +1 -1
  158. package/dist/internal/components/Modal.js +1 -1
  159. package/dist/internal/components/Navbar.js +1 -1
  160. package/dist/internal/components/Pagination.js +1 -1
  161. package/dist/internal/components/Popconfirm.js +1 -1
  162. package/dist/internal/components/RadioGroup.js +1 -1
  163. package/dist/internal/components/Search.js +1 -1
  164. package/dist/internal/components/Select.js +1 -1
  165. package/dist/internal/components/Sheet.js +1 -1
  166. package/dist/internal/components/Sidebar.js +1 -1
  167. package/dist/internal/components/Slider.js +1 -1
  168. package/dist/internal/components/Table.js +1 -1
  169. package/dist/internal/components/Tabs.js +1 -1
  170. package/dist/internal/components/ThemeProvider.js +1 -1
  171. package/dist/internal/components/Tooltip.js +1 -1
  172. package/dist/internal/components/Truncated.js +1 -1
  173. package/dist/internal/components/ZoomableSvg.js +1 -1
  174. package/dist/internal/utils.js +1 -1
  175. package/dist/markdown-editor.js +6 -6
  176. package/dist/mermaid.js +1 -1
  177. package/dist/rjsf.js +11 -11
  178. package/dist/rjsf.js.map +1 -1
  179. package/dist/styles.css +1 -1
  180. package/dist/testing.js +1 -1
  181. package/dist/{utils-DjFceY3H.js → utils-BxEJOnFD.js} +2 -2
  182. package/dist/{utils-DjFceY3H.js.map → utils-BxEJOnFD.js.map} +1 -1
  183. package/package.json +3 -3
  184. package/src/styles.css +50 -0
  185. package/src/theme.css +10 -8
  186. package/dist/AIKit-Cf5plya2.js.map +0 -1
  187. package/dist/Clipboard-fAkDdpEu.js.map +0 -1
  188. package/dist/ClipboardButton-71Ugbl8c.js.map +0 -1
  189. package/dist/SectionNav-L81iJBo3.js.map +0 -1
  190. package/dist/Table-BwgBm3hJ.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"Combobox-DYjvYgl3.js","names":["BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","Combobox","BaseCombobox"],"sources":["../src/components/Combobox/blankValues.ts","../src/components/Combobox/ComboboxChip.tsx","../src/components/Combobox/utils.ts","../src/components/Combobox/ComboboxChips.tsx","../src/components/Combobox/ComboboxClearButton.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/virtualList.ts","../src/components/Combobox/ComboboxItem.tsx","../src/components/Combobox/ComboboxList.tsx","../src/components/Combobox/ComboboxOpenButton.tsx","../src/components/Combobox/Group/ComboboxGroupHeader.tsx","../src/components/Combobox/Group/ComboboxGroup.tsx","../src/components/Combobox/Group/ComboboxGroupLabel.tsx","../src/components/Combobox/Group/ComboboxCollection.tsx","../src/components/Combobox/ComboboxFullList.tsx","../src/components/Combobox/ComboboxLoadingEmpty.tsx","../src/components/Combobox/ComboboxVirtualList.tsx","../src/components/Combobox/ComboboxOptions.tsx","../src/components/Combobox/ComboboxRoot.tsx","../src/components/Combobox/ComboboxSeparator.tsx","../src/components/Combobox/createdItems.ts","../src/components/Combobox/groupFlip.ts","../src/components/Combobox/groupHeaders.ts","../src/components/Combobox/query.ts","../src/components/Combobox/Combobox.tsx","../src/components/Combobox/matchByWords.ts"],"sourcesContent":["/**\n * The two blank strings a Storage filter predicates on, in list order.\n *\n * - Hand it to `items` where the blanks are the whole list — a value field whose other entries the\n * user types. {@link withBlankValues} is for offering them ahead of a list that already exists.\n */\nexport const BLANK_VALUES: readonly string[] = ['', ' '];\n\nconst BLANK_LABELS: Record<string, string> = {\n '': '[empty string]',\n ' ': '[space character]',\n};\n\n/**\n * A string as a row or a chip shows it — named when its text is blank, itself otherwise.\n *\n * - Exported so an `itemToLabel` / `itemToChipLabel` / `itemToSelectedLabel` / `renderChips`\n * override can keep the default naming instead of retyping the labels.\n * - The two blank values get their own labels; any other whitespace-only string (a tab, a run of\n * spaces) falls back to a generic one, so two different ones read alike.\n * - Identity is unaffected — `toLabel` keys items off the raw string.\n */\nexport const namedLabel = (text: string): string =>\n text.trim() === '' ? (BLANK_LABELS[text] ?? '[whitespace]') : text;\n\n/**\n * `values` with both blank values offered ahead of them, and duplicates collapsed.\n *\n * - The dedupe matters where the list is the distinct values of a Storage column: it can already\n * hold a blank, and two `Object.is`-equal rows both report `aria-selected` and toggle each other.\n * - First occurrence wins, so the order of the values is otherwise preserved.\n * - String items only — the seven Storage filters this serves are all string-valued.\n */\nexport const withBlankValues = (values: readonly string[]): string[] => [\n ...new Set([...BLANK_VALUES, ...values]),\n];\n","import { type ComponentProps, type KeyboardEvent, type ReactNode, useState } from 'react';\nimport { Combobox as BaseCombobox } from '@base-ui/react/combobox';\n\nimport { X } from '../../icons';\nimport { Badge } from '../Badge';\nimport { Tooltip, TooltipProvider } from '../Tooltip';\nimport { hasTruncationOverflow } from '../Truncated';\n\nexport type BadgeColor = ComponentProps<typeof Badge>['color'];\nexport type BadgeVariant = ComponentProps<typeof Badge>['variant'];\n\n/**\n * Keeps a chip's keyboard handling off its content's.\n *\n * - Base UI's chip `preventDefault`s Enter/Space, cancelling a nested link or button.\n * - Capture phase, so the chip's own bubble handler never runs.\n * - Target-guarded, so the chip's own keys (Backspace, Delete, arrows) still reach it.\n */\nconst stopNestedKeyDown = (event: KeyboardEvent<HTMLElement>) => {\n if (event.target !== event.currentTarget) event.stopPropagation();\n};\n\ntype Props = {\n children: ReactNode;\n color?: BadgeColor;\n variant?: BadgeVariant;\n};\n\n/**\n * One removable chip in a `MultiCombobox`'s `renderChips` slot or `Combobox.Chips`.\n *\n * - Position is identity: Base UI removes by index, so render one per `value` entry, in order.\n * - A non-removable chip is a plain `Badge`: a chip would shift the removal index.\n * - A label cut off by the chip's width shows in full in a tooltip on hover.\n */\nexport const ComboboxChip = ({ children, color, variant }: Props) => {\n const [isTruncated, setIsTruncated] = useState(false);\n\n return (\n <BaseCombobox.Chip\n render={<Badge.Root color={color} variant={variant ?? 'pill'} className=\"tw:max-w-40\" />}\n onKeyDownCapture={stopNestedKeyDown}\n >\n <TooltipProvider>\n <Tooltip tooltip={children} forceHide={!isTruncated} placement=\"top\" triggerAsChild>\n {/* The trigger's `tailwindcss-preflight` sets `line-height: 1.5`; keep the badge's own. */}\n <Badge.Label\n className=\"tw:leading-[inherit]\"\n onMouseOver={(event) => setIsTruncated(hasTruncationOverflow(event.currentTarget))}\n >\n {children}\n </Badge.Label>\n </Tooltip>\n </TooltipProvider>\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","import { isValidElement, type ReactNode, useMemo } from 'react';\n\nimport { namedLabel } from './blankValues';\nimport type {\n CreatableItem,\n Group,\n GroupHeaderItem,\n InternalItems,\n LabeledItem,\n SelectAllItem,\n} 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\nconst isLabeledItem = (item: unknown): item is LabeledItem =>\n isPlainObject(item) && Reflect.has(item, 'label') && Reflect.has(item, 'value');\n\nexport const 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 isGroupHeaderItem = (item: unknown): item is GroupHeaderItem =>\n isInternalItem(item) && item.__marker === 'groupHeader';\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 empty as non-grouped\n return isGroupItem(items[0]); // Base UI checks only the first item\n};\n\n/** The options of a list, its groups flattened. */\nexport const flatItems = <Value>(list: readonly (Value | Group<Value>)[]) => {\n const items: Value[] = [];\n for (const entry of list) {\n if (!isGroupItem(entry)) items.push(entry);\n // One push per item: spreading a large group would exceed the engine's argument limit.\n else for (const item of entry.items) items.push(item);\n }\n return items;\n};\n\n/** The create row and Select All: each is drawn outside any group, even in a grouped list. */\nexport const isLooseItem = (item: unknown): item is CreatableItem | SelectAllItem =>\n isCreatableItem(item) || isSelectAllItem(item);\n\n/**\n * `items` as entries of `list`: one group without a label in a grouped list, else themselves.\n *\n * - Base UI reads the first entry to tell a grouped list, so every entry has to match it.\n * - The group never reaches `groupToLabel`: {@link isEntriesGroup} tells it apart.\n */\nexport const toEntries = <Item>(list: readonly unknown[], items: readonly Item[]) =>\n isGroupItems(list) ? [{ __marker: 'entries' as const, items }] : items;\n\n/** A group {@link toEntries} made; Base UI's filter keeps the marker, as it spreads each group. */\nexport const isEntriesGroup = (entry: unknown) =>\n isGroupItem(entry) && Reflect.get(entry, '__marker') === 'entries';\n\n/**\n * Node a list row and a chip show for an item.\n *\n * - Names a blank string, so a row or chip never renders as nothing; {@link toLabel} does not.\n * - A non-string `label` (a JSX node) passes through.\n */\nexport const defaultItemToLabel = <Item>(item: Item) => {\n if (isNumber(item)) return item;\n if (isString(item)) return namedLabel(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 isString(item.label) ? namedLabel(item.label) : item.label;\n};\n\n/**\n * The node a row or a chip shows for an item when the caller passes no `itemToLabel`.\n *\n * - Names a blank `itemToStringLabel` result, which would otherwise render as nothing.\n * - Falls back to the item's own string: Base UI reports the outgoing selection for one render\n * after `items` and `itemToStringLabel` change together.\n */\nexport const defaultRowLabel = <Item>(itemToStringLabel?: (item: Item) => string) =>\n itemToStringLabel\n ? (item: Item) => namedLabel(itemToStringLabel(item) ?? toLabel(item))\n : defaultItemToLabel;\n\n/**\n * Display string for an item — mirrors Base UI's default.\n *\n * - Also the default search text and the closed `Combobox`'s input value.\n * - Does not name blank strings: `''` may mean \"nothing selected\", and must keep the placeholder.\n * - A labelled item with neither a label nor a value reads as `''`, like the string item `''`.\n * - Naming lives in {@link defaultItemToLabel}, read only by rows and chips.\n */\nexport const toLabel = (item: unknown): string => {\n if (isString(item)) return item;\n if (isLabeledItem(item)) return item.label || item.value || '';\n return String(item);\n};\n\n/** Equality key for an item — prefers `.value`. */\nconst toValueKey = (item: unknown): string => {\n if (isString(item)) return item;\n if (isLabeledItem(item)) return item.value || item.label || '';\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\n/** A group's `label`, as `Select` renders it; one that is not a node reads as none. */\nexport const defaultGroupToLabel = (group: object): ReactNode => {\n const label: unknown = Reflect.get(group, 'label');\n return isString(label) || isNumber(label) || isValidElement(label) ? label : undefined;\n};\n\n// Internal markers: LabeledItem-shaped sentinels injected into Base UI's items.\n// - `__marker` keeps consumer items and callbacks from colliding with them.\n\nexport const selectAllItem: SelectAllItem = {\n __marker: 'selectAll',\n value: '__select_all__',\n label: 'Select All',\n};\n\n/** Row for the group at `index` — keyed by position, like its collapse state. */\nexport const createGroupHeaderItem = (index: number): GroupHeaderItem => ({\n __marker: 'groupHeader',\n value: `__group_${index}__`,\n label: '',\n});\n\nexport const createCreatableItem = (query: string): CreatableItem => ({\n __marker: 'creatable',\n value: query,\n label: query,\n});\n\n/**\n * Item-equality predicate for a Base UI combobox root.\n *\n * - A sentinel equals a sentinel by marker and value key (the create row is rebuilt per keystroke).\n * - A sentinel never equals a real item.\n * - Real items use the caller's predicate, else `Object.is`.\n */\nexport const toItemEquality =\n <Value>(isItemEqualToValue?: (a: Value, b: Value) => boolean) =>\n (a: Value, b: Value) => {\n if (isInternalItem(a) || isInternalItem(b)) {\n return (\n isInternalItem(a) &&\n isInternalItem(b) &&\n a.__marker === b.__marker &&\n toValueKey(a) === toValueKey(b)\n );\n }\n return isItemEqualToValue?.(a, b) ?? Object.is(a, b);\n };\n\n/**\n * {@link toItemEquality} with a stable identity.\n *\n * - Base UI lists the comparer in an effect's deps; a new one per render re-renders every row.\n */\nexport const useItemEquality = <Value>(isItemEqualToValue?: (a: Value, b: Value) => boolean) =>\n useMemo(() => toItemEquality(isItemEqualToValue), [isItemEqualToValue]);\n\n/** `itemToStringValue` that also reads the create row, whose value is its query. */\nexport const withCreatableStringValue = <Value>(\n itemToStringValue: ((item: Value) => string) | undefined,\n allowCreate: boolean | undefined,\n) =>\n !allowCreate || !itemToStringValue\n ? itemToStringValue\n : (item: Value) => (isCreatableItem(item) ? item.value : itemToStringValue(item));\n\n/** {@link withCreatableStringValue} with a stable identity. */\nexport const useCreatableStringValue = <Value>(\n itemToStringValue: ((item: Value) => string) | undefined,\n allowCreate: boolean | undefined,\n) =>\n useMemo(\n () => withCreatableStringValue(itemToStringValue, allowCreate),\n [itemToStringValue, allowCreate],\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 { ReactNode } from 'react';\nimport { Combobox as BaseCombobox } from '@base-ui/react/combobox';\n\nimport { Badge } from '../Badge';\n\nimport { type BadgeColor, type BadgeVariant, ComboboxChip } from './ComboboxChip';\nimport { defaultItemToLabel, isInternalItem } from './utils';\n\ntype Props<Value> = {\n maxVisible?: number;\n itemToChipLabel?: (item: Value) => ReactNode;\n itemToChipColor?: (item: Value) => BadgeColor;\n /**\n * Non-removable chips ahead of the values, outside `maxVisible` and absent from `value`.\n */\n pinnedChipLabels?: ReactNode[];\n variant?: BadgeVariant;\n /**\n * Renders the chip area in place of the default chips; every other prop is then unused.\n */\n children?: (values: Value[]) => ReactNode;\n};\n\nexport const ComboboxChips = <Value,>({\n maxVisible = 3,\n itemToChipLabel = defaultItemToLabel,\n itemToChipColor,\n pinnedChipLabels,\n variant = 'pill',\n children,\n}: Props<Value>) => (\n <BaseCombobox.Value>\n {(rawValues: Value[]) => {\n // Drop the Select All marker Base UI keeps in `value`: it gets no chip and never reaches\n // the caller's `itemToChipLabel` / `itemToChipColor`.\n const values = rawValues.filter((value) => !isInternalItem(value));\n\n if (children) return children(values);\n\n const visible = values.slice(0, maxVisible);\n const overflow = values.slice(maxVisible);\n\n return (\n <>\n {pinnedChipLabels?.map((label, index) => (\n // oxlint-disable-next-line react/no-array-index-key\n <Badge key={index} className=\"tw:max-w-40\" variant={variant}>\n {label}\n </Badge>\n ))}\n\n {visible.map((value: Value, index) => (\n <ComboboxChip\n // oxlint-disable-next-line react/no-array-index-key\n key={index}\n color={itemToChipColor?.(value)}\n variant={variant}\n >\n {itemToChipLabel(value)}\n </ComboboxChip>\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 { Combobox as BaseCombobox } from '@base-ui/react/combobox';\n\nimport { X } from '../../icons';\nimport { InputGroup } from '../InputGroup';\n\ntype Props = {\n disabled?: boolean;\n};\n\n/** The button that clears the selection. */\nexport const ComboboxClearButton = ({ disabled }: Props) => (\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","import type { ComponentProps } from 'react';\nimport { Combobox as BaseCombobox } from '@base-ui/react/combobox';\nimport { DismissableLayer } from '@radix-ui/react-dismissable-layer';\n\nimport { cn } from '../../utils';\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 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 return (\n <BaseCombobox.Portal container={container}>\n {/*\n * Registers the popup in Radix's layer stack.\n *\n * - Base UI portals the popup out of the DOM, so a surrounding Radix `Modal` / `Sheet` /\n * `Popover` would otherwise still count itself as topmost and close on Escape. Radix reads\n * the key off a document capture listener, so being a higher layer is the only lever.\n * - No `onDismiss`: Base UI closes the popup itself, the layer only claims the keystroke.\n */}\n <DismissableLayer asChild>\n <BaseCombobox.Positioner\n align={align}\n side={side}\n sideOffset={sideOffset}\n alignOffset={alignOffset}\n anchor={anchor}\n className=\"tw:isolate tw:z-overlay tailwindcss-preflight\"\n >\n <BaseCombobox.Popup\n ref={ref}\n data-slot=\"combobox-content\"\n data-chips={!!anchor}\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\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 </DismissableLayer>\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 type { WithAccessibleName } from '../../utils/accessibleName';\nimport { InputGroup } from '../InputGroup';\n\n/** The input carries the `combobox` role, so the name is required here, not on the group. */\ntype Props = WithAccessibleName<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<ComponentProps<typeof InputGroup>, 'focusVariant' | 'state'>;\n\ntype Props = InputGroupProps &\n Omit<ComponentProps<typeof BaseCombobox.InputGroup>, 'render' | 'className'> & {\n className?: string;\n };\n\nexport const ComboboxInputGroup = ({ ref, state, focusVariant, className, ...props }: Props) => (\n <BaseCombobox.InputGroup\n {...props}\n ref={ref}\n render={<InputGroup state={state} focusVariant={focusVariant} className={className} />}\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 // `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-hover-foreground',\n className,\n )}\n render={<Check />}\n />\n );\n};\n","import { createContext, useRef } from 'react';\n\nimport { isGroupItems } from './utils';\n\n/** Above this many options, `virtualized=\"auto\"` windows the list. */\nconst VIRTUALIZE_THRESHOLD = 30;\n\nexport type VirtualizedProps = {\n /** Puts only the rows in view into the DOM: `'auto'` past 30 options, grouped or not; `true` always. */\n virtualized?: boolean | 'auto';\n};\n\n/** Scrolls the option at Base UI's flat `index` into view, unless it is in view already. */\nexport type VirtualListHandle = { scrollToItem: (index: number) => void };\n\n/**\n * The position a windowed list gives each option it renders.\n *\n * - `index` is the option's place in Base UI's flat filtered list, which keyboard navigation counts.\n * - `aria-setsize` / `aria-posinset` keep the set's length known while most options are out of the DOM.\n * - `undefined` outside a windowed list, so a fully rendered list keeps its markup.\n */\nexport const VirtualRowContext = createContext<\n { index: number; 'aria-setsize': number; 'aria-posinset': number } | undefined\n>(undefined);\n\n/**\n * Whether a combobox windows its list, and what ties Base UI's highlight to the window.\n *\n * - `'auto'` counts options, not groups, so a list of a few large groups windows too.\n * - `onItemHighlighted` scrolls a row the keyboard reached into view; a pointer is over its row.\n * - `ref` goes to `ComboboxVirtualList`.\n */\nexport const useVirtualList = (\n items: readonly unknown[],\n virtualized: NonNullable<VirtualizedProps['virtualized']>,\n) => {\n const ref = useRef<VirtualListHandle>(null);\n const count = isGroupItems(items)\n ? items.reduce((sum, group) => sum + group.items.length, 0)\n : items.length;\n\n return {\n enabled: virtualized === 'auto' ? count > VIRTUALIZE_THRESHOLD : virtualized,\n ref,\n onItemHighlighted: ({ reason, index }: { reason: string; index: number }) => {\n if (reason !== 'pointer') ref.current?.scrollToItem(index);\n },\n };\n};\n","import { type ComponentProps, type ReactNode, use } from 'react';\nimport { Combobox as BaseCombobox } from '@base-ui/react/combobox';\n\nimport { cn } from '../../utils';\n\nimport { ComboboxItemIndicator } from './ComboboxItemIndicator';\nimport { VirtualRowContext } from './virtualList';\n\ntype Props = Omit<ComponentProps<typeof BaseCombobox.Item>, 'className'> & {\n className?: string;\n icon?: ReactNode;\n /** `'none'` leaves the row without one — a row that draws its own state in `icon`. */\n indicator?: ComponentProps<typeof ComboboxItemIndicator>['variant'] | 'none';\n /** Looks disabled but still takes the highlight; the owning control ignores its presses. */\n locked?: boolean;\n};\n\nexport const ComboboxItem = ({\n ref,\n className,\n children,\n icon,\n indicator: variant = 'check',\n locked,\n ...props\n}: Props) => (\n <BaseCombobox.Item\n {...props}\n {...use(VirtualRowContext)}\n ref={ref}\n data-slot=\"combobox-item\"\n data-locked={locked || undefined}\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:rounded-lg',\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-hover',\n 'tw:data-[highlighted]:text-hover-foreground',\n\n // disabled\n 'tw:data-disabled:pointer-events-none',\n 'tw:data-disabled:opacity-disabled',\n 'tw:data-locked:opacity-disabled',\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 {variant !== 'none' && <ComboboxItemIndicator variant={variant} />}\n {icon}\n {/* Wraps rather than truncates; fills the row so a label can push content to its end. */}\n {/* `data-slot`: a host aligning the leading marks to the label's first line targets it. */}\n <span data-slot=\"combobox-item-label\" className=\"tw:min-w-0 tw:flex-1 tw:wrap-anywhere\">\n {children}\n </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 className,\n )}\n {...props}\n />\n);\n","import { Combobox as BaseCombobox } from '@base-ui/react/combobox';\n\nimport { ChevronDown, Loader2 } from '../../icons';\nimport { InputGroup } from '../InputGroup';\n\ntype Props = {\n disabled?: boolean;\n isLoading: boolean;\n};\n\n/**\n * The button that opens the popup: a chevron, or a spinner while the options are loading.\n *\n * - The spinner swaps in for the icon inside the one button, which costs the control no width, so\n * the input keeps its room whether or not a request is in flight.\n * - The button keeps opening the popup while loading, so a list that already has items stays\n * reachable.\n */\nexport const ComboboxOpenButton = ({ disabled, isLoading }: Props) => (\n <InputGroup.Button disabled={disabled} asChild aria-label=\"Open combobox\">\n <BaseCombobox.Trigger>\n {isLoading ? (\n <Loader2 className=\"tw:size-4 tw:animate-spin\" />\n ) : (\n <ChevronDown className=\"tw:size-4\" />\n )}\n </BaseCombobox.Trigger>\n </InputGroup.Button>\n);\n","import type { MouseEvent, ReactNode } from 'react';\n\nimport { Check, ChevronRight, Minus } from '../../../icons';\nimport { cn } from '../../../utils';\nimport { isToggleAllClick } from '../../Tooltip/toggleAll';\nimport { ToggleAllTooltip } from '../../Tooltip/ToggleAllTooltip';\nimport { ComboboxItem } from '../ComboboxItem';\n\n/** Indent of a header's children (chevron + gap). */\nexport const GROUP_CHILD_INDENT = 'tw:pl-8';\n\ntype Props = {\n value: unknown;\n children: ReactNode;\n /** `undefined` for a group that does not collapse — no chevron. */\n expanded?: boolean;\n /** `all` for a Cmd-click (Ctrl elsewhere): fold or unfold every group; `from` is in the list. */\n onToggle: (all: boolean, from: Element) => void;\n /**\n * `'mixed'` for a partial selection; `undefined` for an unselectable row that toggles on press.\n * Drawn here: Base UI would put its indicator ahead of the chevron.\n */\n checked?: boolean | 'mixed';\n /** The children's indicator, mirrored by a `checked` row. */\n indicator?: 'check' | 'checkbox';\n disabled?: boolean;\n /** Every item it would pick is locked: looks disabled, still highlights. */\n locked?: boolean;\n};\n\n/**\n * A group's own row, standing for the whole group.\n *\n * - Keyboard-navigable like any other row.\n * - The chevron toggles by pointer, Cmd- or Ctrl-click toggles every group; its tooltip says so.\n * - `ArrowRight` / `ArrowLeft` are handled by the owning control.\n */\nexport const ComboboxGroupHeader = ({\n value,\n children,\n expanded,\n onToggle,\n checked,\n indicator = 'check',\n disabled,\n locked,\n}: Props) => {\n const toggleFromChevron = (event: MouseEvent) => {\n // Keep the chevron's click from selecting a selectable row.\n event.stopPropagation();\n onToggle(isToggleAllClick(event), event.currentTarget);\n };\n\n return (\n <ComboboxItem\n value={value}\n disabled={disabled}\n locked={locked}\n // An option allows no `aria-expanded`; screen readers read the description after the name.\n aria-description={expanded === undefined ? undefined : expanded ? 'Expanded' : 'Collapsed'}\n {...(checked !== undefined && { 'aria-selected': checked === true })}\n indicator=\"none\"\n className=\"tw:font-medium\"\n onClick={\n checked !== undefined\n ? undefined\n : (event) => {\n event.preventBaseUIHandler();\n onToggle(isToggleAllClick(event), event.currentTarget);\n }\n }\n icon={\n <>\n {expanded !== undefined && (\n <ToggleAllTooltip expanded={expanded}>\n <span\n aria-hidden\n data-slot=\"combobox-group-toggle\"\n // An icon button: its own hover, and it still folds a disabled row.\n className=\"tw:pointer-events-auto tw:-m-1 tw:inline-flex tw:shrink-0 tw:cursor-pointer tw:rounded tw:p-1 tw:transition-colors tw:hover:bg-foreground/10\"\n onClick={toggleFromChevron}\n >\n <ChevronRight\n className={cn('tw:transition-transform', expanded && 'tw:rotate-90')}\n />\n </span>\n </ToggleAllTooltip>\n )}\n {checked !== undefined && <GroupIndicator checked={checked} variant={indicator} />}\n </>\n }\n >\n {children}\n </ComboboxItem>\n );\n};\n\n/**\n * A group row's selection mark: all, some, or none.\n *\n * - Base UI's indicator is binary, so the row draws its own.\n * - `checkbox` matches the children's leading box; `check` their trailing mark.\n */\nconst GroupIndicator = ({\n checked,\n variant,\n}: {\n checked: boolean | 'mixed';\n variant: 'check' | 'checkbox';\n}) => {\n const Mark = checked === 'mixed' ? Minus : Check;\n\n if (variant === 'checkbox') {\n return (\n <span\n aria-hidden\n data-checked={checked}\n className={cn(\n 'tw:inline-flex tw:size-4 tw:shrink-0 tw:items-center tw:justify-center',\n 'tw:rounded tw:border tw:border-input tw:bg-background',\n checked !== false && 'tw:border-primary tw:bg-primary',\n )}\n >\n {checked !== false && (\n <Mark className=\"tw:size-3 tw:stroke-[4px] tw:!text-primary-foreground\" />\n )}\n </span>\n );\n }\n\n if (checked === false) return null;\n\n return (\n <Mark\n aria-hidden\n className={cn(\n 'tw:pointer-events-none tw:absolute tw:right-2 tw:size-4',\n 'tw:group-data-[highlighted]/combobox-item:text-hover-foreground',\n )}\n />\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 // Soft grey 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 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 { Fragment, type ReactNode } from 'react';\n\nimport { ComboboxList } from './ComboboxList';\nimport { ComboboxCollection, ComboboxGroup, ComboboxGroupLabel } from './Group';\nimport type { Group, ListRenderProps } from './types';\nimport { isGroupItem, isLooseItem } from './utils';\n\n/** A Base UI collection child whose rows are keyed by position, as React matches unkeyed ones. */\nconst keyed =\n <Entry,>(render: (entry: Entry) => ReactNode) =>\n (entry: Entry, index: number) =>\n (\n // oxlint-disable-next-line react/no-array-index-key\n <Fragment key={index}>{render(entry)}</Fragment>\n );\n\n/** A combobox list that renders every row; `ComboboxVirtualList` renders only those in view. */\nexport const ComboboxFullList = <Value, GroupShape extends Group<Value> = Group<Value>>({\n renderItem,\n renderGroupItem,\n groupToLabel,\n}: ListRenderProps<Value, GroupShape>) => {\n const renderEntry = (entry: Value | GroupShape) => {\n if (!isGroupItem(entry)) return renderItem(entry);\n\n const [lead] = entry.items;\n if (isLooseItem(lead)) return renderItem(lead);\n\n const label = groupToLabel?.(entry);\n return (\n <ComboboxGroup items={entry.items}>\n {label && <ComboboxGroupLabel>{label}</ComboboxGroupLabel>}\n <ComboboxCollection>{keyed(renderGroupItem)}</ComboboxCollection>\n </ComboboxGroup>\n );\n };\n\n return <ComboboxList>{keyed(renderEntry)}</ComboboxList>;\n};\n","import { Loader2 } from '../../icons';\n\n/**\n * What the empty slot says while the options are loading, in place of the `empty` node.\n *\n * - `Combobox.Empty` is a polite live region, so the switch to this text and back to `empty` once\n * the request settles is announced.\n * - Base UI renders the slot only while the list has nothing to show, so a list that already has\n * items keeps showing them.\n */\nexport const ComboboxLoadingEmpty = () => (\n <span className=\"tw:inline-flex tw:items-center tw:gap-2\">\n <Loader2 className=\"tw:size-4 tw:animate-spin\" />\n Loading…\n </span>\n);\n","import {\n type CSSProperties,\n type ReactNode,\n type Ref,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { Combobox as BaseCombobox } from '@base-ui/react/combobox';\nimport {\n measureElement,\n observeElementRect,\n useVirtualizer,\n type VirtualItem,\n} from '@tanstack/react-virtual';\n\nimport { useElement } from '../../hooks/useElement';\n\nimport { ComboboxList } from './ComboboxList';\nimport { ComboboxGroup, ComboboxGroupLabel } from './Group';\nimport type { Group, ListRenderProps } from './types';\nimport { isGroupItem, isGroupItems, isLooseItem } from './utils';\nimport { type VirtualListHandle, VirtualRowContext } from './virtualList';\n\n/** Rows rendered past each edge of the viewport, so a fast scroll does not paint blank. */\nconst OVERSCAN = 12;\n\ntype ItemRow<Value> = {\n type: 'item';\n item: Value;\n /** Place in Base UI's flat filtered list. */\n index: number;\n setSize: number;\n posInSet: number;\n};\n\ntype Row<Value> = (ItemRow<Value> | { type: 'label' }) & {\n /** The group whose wrapper the row shares; `undefined` for a row outside any group. */\n group?: string;\n /** Spaced from the row above by the gap a fully rendered group puts between its children. */\n padded: boolean;\n};\n\n/** A group's last row is its own kind: a host may space groups apart inside it. */\ntype Kind = 'label' | 'padded' | 'plain' | 'padded-last' | 'plain-last';\nconst isGroupLast = (row: Row<unknown>) =>\n row.type === 'item' && row.group !== undefined && row.posInSet === row.setSize;\nconst kindOf = (row: Row<unknown>): Kind =>\n row.type === 'label'\n ? 'label'\n : `${row.padded ? 'padded' : 'plain'}${isGroupLast(row) ? '-last' : ''}`;\n\n/** A row's React key: its group and its place in it, so a fold leaves other rows mounted. */\nconst placeOf = (row: Row<unknown> | undefined, index: number) => {\n if (!row) return String(index);\n if (row.type === 'label') return `${row.group}:label`;\n return `${row.group ?? 'loose'}:${row.posInSet}`;\n};\n\n/**\n * A row's key for the virtualizer, which keeps measured heights by it.\n *\n * - Folding one group leaves every other row's height in place.\n * - A row that becomes its group's last is estimated afresh, its element kept.\n */\nconst keyOf = (row: Row<unknown> | undefined, index: number) =>\n `${placeOf(row, index)}${row && isGroupLast(row) ? ':last' : ''}`;\n\n/**\n * Base UI's filtered entries as one row per option or group label, in list order.\n *\n * - A group whose lone item is the create row or Select All stays outside any group, as the fully\n * rendered list draws it.\n * - `aria-setsize` counts the options sharing a parent, as a browser does for a rendered list.\n */\nconst toRows = <Value, GroupShape extends Group<Value>>(\n entries: readonly (Value | GroupShape)[],\n groupToLabel: ((group: GroupShape) => ReactNode) | undefined,\n) => {\n const rows: Row<Value>[] = [];\n const rowOfItem: number[] = [];\n const labels = new Map<string, ReactNode>();\n const push = (item: Value, row: Omit<Row<Value> & ItemRow<Value>, 'type' | 'item' | 'index'>) => {\n rows.push({ type: 'item', item, index: rowOfItem.length, ...row });\n rowOfItem.push(rows.length - 1);\n };\n\n if (!isGroupItems<Value, GroupShape>(entries)) {\n const items = entries.filter((entry): entry is Value => !isGroupItem(entry));\n items.forEach((item, i) =>\n push(item, { padded: false, setSize: items.length, posInSet: i + 1 }),\n );\n return { rows, rowOfItem, labels };\n }\n\n const isLoose = (group: GroupShape) => isLooseItem(group.items[0]);\n const looseCount = entries.filter(isLoose).length;\n let loosePosition = 0;\n\n entries.forEach((entry, groupIndex) => {\n if (isLoose(entry)) {\n for (const item of entry.items) {\n push(item, { padded: false, setSize: looseCount, posInSet: ++loosePosition });\n }\n return;\n }\n\n const group = `group-${groupIndex}`;\n const label = groupToLabel?.(entry);\n if (label) {\n labels.set(group, label);\n rows.push({ type: 'label', group, padded: false });\n }\n entry.items.forEach((item, i) =>\n push(item, {\n group,\n padded: Boolean(label) || i > 0,\n setSize: entry.items.length,\n posInSet: i + 1,\n }),\n );\n });\n\n return { rows, rowOfItem, labels };\n};\n\ntype Props<Value, GroupShape extends Group<Value>> = ListRenderProps<Value, GroupShape> & {\n ref?: Ref<VirtualListHandle>;\n};\n\n/**\n * A combobox list that puts only the rows in view into the DOM.\n *\n * - Lists what Base UI filtered, so search and keyboard navigation cover every option.\n * - A group keeps its `role=\"group\"` wrapper, and its name while its label row is out of view.\n * - Rows keep their own height; a row not yet rendered is estimated from those that were.\n */\nexport const ComboboxVirtualList = <Value, GroupShape extends Group<Value> = Group<Value>>({\n renderItem,\n renderGroupItem,\n groupToLabel,\n ref,\n}: Props<Value, GroupShape>) => {\n // State, not a ref: the list mounts with the popup, and its top padding — which the rows start\n // below — is read once it has.\n const [listElement, attachList] = useElement();\n const scrollMargin = useMemo(\n () => (listElement ? Number.parseFloat(getComputedStyle(listElement).paddingTop) || 0 : 0),\n [listElement],\n );\n const filteredItems = BaseCombobox.useFilteredItems<Value | GroupShape>();\n const { rows, rowOfItem, labels } = useMemo(\n () => toRows<Value, GroupShape>(filteredItems, groupToLabel),\n [filteredItems, groupToLabel],\n );\n\n // The smallest height each kind of row has rendered at; 1rem stands in until one has.\n const sizesRef = useRef<Partial<Record<Kind, number>>>({});\n const [rem] = useState(\n () => Number.parseFloat(getComputedStyle(document.documentElement).fontSize) || 0,\n );\n\n const virtualizer = useVirtualizer({\n count: rows.length,\n getItemKey: (index) => keyOf(rows[index], index),\n getScrollElement: () => listElement,\n estimateSize: (index) => {\n const row = rows[index];\n const measured = sizesRef.current;\n const kind = row && kindOf(row);\n const lastKinds = kind?.endsWith('-last')\n ? [measured['plain-last'], measured['padded-last']]\n : [];\n return (\n (kind && measured[kind]) ??\n lastKinds.find((size) => size !== undefined) ??\n measured.plain ??\n measured.padded ??\n rem\n );\n },\n measureElement: (element, entry, instance) => {\n const size = measureElement(element, entry, instance);\n const row = rows[instance.indexFromElement(element)];\n if (row) {\n const kind = kindOf(row);\n sizesRef.current[kind] = Math.min(sizesRef.current[kind] ?? size, size);\n }\n return size;\n },\n // The popup is unbounded until Base UI positions it, and never taller than the window once it\n // is — so the first reading would otherwise mount every row.\n observeElementRect: (instance, callback) =>\n observeElementRect(instance, (rect) =>\n callback({\n ...rect,\n height: Math.min(rect.height, instance.targetWindow?.innerHeight ?? rect.height),\n }),\n ),\n overscan: OVERSCAN,\n scrollMargin,\n });\n\n useImperativeHandle(ref, () => ({\n scrollToItem: (index) => {\n const row = rowOfItem[index];\n if (row !== undefined) virtualizer.scrollToIndex(row, { align: 'auto' });\n },\n }));\n\n // Consecutive rows of one group share its wrapper; a row outside any group stands alone.\n const segments: { group?: string; start: number; items: VirtualItem[] }[] = [];\n for (const virtualItem of virtualizer.getVirtualItems()) {\n const group = rows[virtualItem.index]?.group;\n const last = segments.at(-1);\n if (group !== undefined && last?.group === group) last.items.push(virtualItem);\n else segments.push({ group, start: virtualItem.start, items: [virtualItem] });\n }\n\n const placeAt = (start: number): CSSProperties => ({\n position: 'absolute',\n top: 0,\n left: 0,\n width: '100%',\n transform: `translateY(${start - scrollMargin}px)`,\n });\n\n const renderRow = ({ index, start }: VirtualItem) => {\n const row = rows[index];\n if (!row) return null;\n return (\n <div\n key={placeOf(row, index)}\n data-index={index}\n ref={virtualizer.measureElement}\n className={row.padded ? 'tw:pt-0.5' : undefined}\n style={row.group === undefined ? placeAt(start) : undefined}\n // A group's last row, for a host that spaces groups apart inside the measured rows.\n data-group-last={isGroupLast(row) ? '' : undefined}\n >\n {row.type === 'label' ? (\n <ComboboxGroupLabel>{labels.get(row.group ?? '')}</ComboboxGroupLabel>\n ) : (\n <VirtualRowContext\n value={{\n index: row.index,\n 'aria-setsize': row.setSize,\n 'aria-posinset': row.posInSet,\n }}\n >\n {row.group === undefined ? renderItem(row.item) : renderGroupItem(row.item)}\n </VirtualRowContext>\n )}\n </div>\n );\n };\n\n return (\n <ComboboxList ref={attachList}>\n <div\n style={{ position: 'relative', width: '100%', height: `${virtualizer.getTotalSize()}px` }}\n >\n {segments.flatMap(({ group, start, items }) => {\n if (group === undefined) return items.map(renderRow);\n\n const label = labels.get(group);\n const labelInView = items.some((item) => rows[item.index]?.type === 'label');\n return (\n <ComboboxGroup key={group} className=\"tw:gap-0\" style={placeAt(start)}>\n {label && !labelInView && (\n <ComboboxGroupLabel className=\"tw:sr-only\">{label}</ComboboxGroupLabel>\n )}\n {items.map(renderRow)}\n </ComboboxGroup>\n );\n })}\n </div>\n </ComboboxList>\n );\n};\n","import { type ComponentProps, type ReactNode, type Ref, useCallback } from 'react';\n\nimport { Plus } from '../../icons';\nimport { cn } from '../../utils';\n\nimport { ComboboxGroupHeader, GROUP_CHILD_INDENT } from './Group/ComboboxGroupHeader';\nimport { ComboboxEmpty } from './ComboboxEmpty';\nimport { ComboboxFullList } from './ComboboxFullList';\nimport { ComboboxItem } from './ComboboxItem';\nimport { ComboboxLoadingEmpty } from './ComboboxLoadingEmpty';\nimport { ComboboxVirtualList } from './ComboboxVirtualList';\nimport type { GroupHeaders } from './groupHeaders';\nimport type { Group } from './types';\nimport { isCreatableItem, isEntriesGroup, isSelectAllItem } from './utils';\nimport type { VirtualListHandle } from './virtualList';\n\ntype GroupHeaderProps = ComponentProps<typeof ComboboxGroupHeader>;\n\n/** A group's items fade and slide in as it unfolds and out as it folds; nothing under reduced motion. */\nconst ITEM_MOTION = {\n entering:\n 'tw:motion-safe:animate-in tw:motion-safe:fade-in-0 tw:motion-safe:slide-in-from-top-1 tw:motion-safe:duration-150 tw:motion-safe:ease-out',\n leaving:\n 'tw:motion-safe:animate-out tw:motion-safe:fade-out-0 tw:motion-safe:slide-out-to-top-1 tw:motion-safe:duration-100 tw:motion-safe:ease-in tw:motion-safe:fill-mode-forwards',\n} as const;\n\ntype Props<Value, GroupShape extends Group<Value>> = {\n isLoading: boolean;\n empty: ReactNode;\n /** Windows the list; `listRef` then reaches the windowed list. */\n virtualized: boolean;\n listRef: Ref<VirtualListHandle>;\n groupHeaders: GroupHeaders<Value, GroupShape>;\n groupToLabel: (group: GroupShape) => ReactNode;\n indicator?: GroupHeaderProps['indicator'];\n itemToLabel: (item: Value) => ReactNode;\n itemToIcon: (item: Value) => ReactNode;\n itemToDisabled: (item: Value) => boolean;\n /** A selected item the user can't remove: looks disabled, still highlights. */\n itemToLocked?: (item: Value) => boolean;\n /** The create row's text; receives the row's value. */\n createLabel: (value: string) => ReactNode;\n /** A selectable group row's mark and state; left unset, a group row only folds. */\n groupRowState?: (\n row: Value,\n ) => Required<Pick<GroupHeaderProps, 'checked' | 'disabled'>> & Pick<GroupHeaderProps, 'locked'>;\n};\n\n/**\n * What a combobox popup lists: every row, the empty slot, and the loading text in it.\n *\n * - The list is windowed while `virtualized`, fully rendered otherwise.\n */\nexport const ComboboxOptions = <Value, GroupShape extends Group<Value> = Group<Value>>({\n isLoading,\n empty,\n virtualized,\n listRef,\n groupHeaders,\n groupToLabel,\n indicator,\n itemToLabel,\n itemToIcon,\n itemToDisabled,\n itemToLocked,\n createLabel,\n groupRowState,\n}: Props<Value, GroupShape>) => {\n const renderItem = (item: Value, className?: string) => {\n if (isSelectAllItem(item)) {\n return (\n <ComboboxItem value={item} indicator=\"checkbox\">\n {item.label}\n </ComboboxItem>\n );\n }\n if (isCreatableItem(item)) {\n return (\n <ComboboxItem value={item} icon={<Plus />}>\n {createLabel(item.value)}\n </ComboboxItem>\n );\n }\n\n return (\n <ComboboxItem\n value={item}\n indicator={indicator}\n icon={itemToIcon(item)}\n disabled={itemToDisabled(item)}\n locked={itemToLocked?.(item)}\n className={className}\n >\n {itemToLabel(item)}\n </ComboboxItem>\n );\n };\n\n const renderGroupItem = (item: Value) => {\n const header = groupHeaders.headerOf(item);\n if (!header) {\n const motion = groupHeaders.motionOf(item);\n return renderItem(\n item,\n cn(groupHeaders.collapsible && GROUP_CHILD_INDENT, motion && ITEM_MOTION[motion]),\n );\n }\n\n const state = groupRowState?.(item);\n return (\n <ComboboxGroupHeader\n value={item}\n expanded={groupHeaders.collapsible ? !header.collapsed : undefined}\n onToggle={(all, from) =>\n all\n ? groupHeaders.setAllCollapsed(!header.collapsed, from)\n : groupHeaders.toggle(header.index, from)\n }\n checked={state?.checked}\n indicator={indicator}\n disabled={state?.disabled ?? false}\n locked={state?.locked}\n >\n {groupToLabel(header.group)}\n </ComboboxGroupHeader>\n );\n };\n\n // Skips the group `toEntries` made; stable, since the windowed list memoizes its rows on it.\n const labelOfGroup = useCallback(\n (group: GroupShape) => (isEntriesGroup(group) ? undefined : groupToLabel(group)),\n [groupToLabel],\n );\n\n const listProps = {\n renderItem,\n renderGroupItem,\n groupToLabel: groupHeaders.enabled ? undefined : labelOfGroup,\n };\n\n return (\n <>\n <ComboboxEmpty>{isLoading ? <ComboboxLoadingEmpty /> : empty}</ComboboxEmpty>\n {virtualized ? (\n <ComboboxVirtualList<Value, GroupShape> ref={listRef} {...listProps} />\n ) : (\n <ComboboxFullList<Value, GroupShape> {...listProps} />\n )}\n </>\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 { useMemo } from 'react';\n\nimport { toEntries } from './utils';\n\n/**\n * `list` followed by the values `allowCreate` minted, as entries of it; stable while both are.\n *\n * - Listed so a created value stays pickable: Base UI drops a value missing from `items`.\n */\nexport const useWithCreated = <Entry, Value>(list: readonly Entry[], created: readonly Value[]) =>\n useMemo(\n () => (created.length === 0 ? list : [...list, ...toEntries(list, created)]),\n [list, created],\n );\n","import { useLayoutEffect, useRef } from 'react';\n\n/** How long the groups under a fold take to slide to their new place. */\nconst SLIDE_MS = 150;\n/** A capture no commit moved anything for in this long is dropped. */\nconst STALE_MS = 500;\n\ntype Capture = { list: Element; tops: Map<Element, number>; at: number };\n\nconst listOf = (from: Element) =>\n from.closest('[role=listbox]') ??\n from.ownerDocument.getElementById(from.getAttribute('aria-controls') ?? '');\n\nconst topIn = (list: Element, element: Element) =>\n element.getBoundingClientRect().top - list.getBoundingClientRect().top + list.scrollTop;\n\n/**\n * Slides a list's groups from where they sat before a fold to where it puts them.\n *\n * - `capture` records each group's place; the next commit that moves one plays the slide.\n * - A group the windowed list only now renders slides by the move of the group above it.\n * - The caller skips `capture` under reduced motion; nothing plays without Web Animations.\n */\nexport const useGroupFlip = (enabled: boolean) => {\n const captureRef = useRef<Capture | null>(null);\n const slidesRef = useRef(new WeakMap<Element, { animation: Animation; shift: number }>());\n\n // Where a group sits without the slide it is still playing.\n const settledTop = (list: Element, group: Element) => {\n const slide = slidesRef.current.get(group);\n const progress = slide?.animation.effect?.getComputedTiming().progress;\n const offset = slide && typeof progress === 'number' ? slide.shift * (1 - progress) : 0;\n return topIn(list, group) - offset;\n };\n\n useLayoutEffect(() => {\n const capture = captureRef.current;\n if (!capture) return;\n if (performance.now() - capture.at > STALE_MS) {\n captureRef.current = null;\n return;\n }\n\n const groups = [...capture.list.querySelectorAll('[role=group]')];\n let lastShift = 0;\n const shifts = groups.map((group) => {\n const before = capture.tops.get(group);\n const shift = before === undefined ? lastShift : before - settledTop(capture.list, group);\n lastShift = shift;\n return shift;\n });\n if (shifts.every((shift) => Math.abs(shift) < 0.5)) return;\n\n captureRef.current = null;\n groups.forEach((group, index) => {\n const shift = shifts[index] ?? 0;\n slidesRef.current.get(group)?.animation.cancel();\n if (Math.abs(shift) < 0.5) return;\n const animation = group.animate(\n [{ transform: `translateY(${shift}px)` }, { transform: 'translateY(0)' }],\n { duration: SLIDE_MS, easing: 'ease-out', composite: 'add' },\n );\n slidesRef.current.set(group, { animation, shift });\n });\n });\n\n return {\n /** Records where the groups of the list `from` belongs to sit now. */\n capture: (from: Element | null | undefined) => {\n const list = from && listOf(from);\n if (!enabled || !list || typeof list.animate !== 'function') return;\n const tops = new Map<Element, number>();\n for (const group of list.querySelectorAll('[role=group]')) {\n tops.set(group, topIn(list, group));\n }\n captureRef.current = { list, tops, at: performance.now() };\n },\n };\n};\n","import { type KeyboardEvent, useEffect, useLayoutEffect, useRef, useState } from 'react';\nimport type { BaseUIEvent } from '@base-ui/react/types';\n\nimport { useGroupFlip } from './groupFlip';\nimport type { Group } from './types';\nimport { createGroupHeaderItem, isGroupItems } from './utils';\n\ntype Header<Value, GroupShape extends Group<Value>> = {\n group: GroupShape;\n index: number;\n /** Whether the group hides its items — never while a query is active. */\n collapsed: boolean;\n /** Items matching the query — all of them without a query. */\n matching: readonly Value[];\n};\n\n/** How long a folding group's items fade out before they leave the list. */\nconst FOLD_MS = 100;\n/** How long an unfolding group's items animate in; their marker clears after it. */\nconst ENTER_MS = 150;\n\nconst NO_FOLDS: ReadonlySet<number> = new Set();\n\nconst hasMotion = () =>\n typeof window.matchMedia === 'function' &&\n !window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n\ntype Options<Value, GroupShape extends Group<Value>> = {\n items: readonly (Value | GroupShape)[];\n collapsible: boolean;\n selectable: boolean;\n query: string;\n /** Only called while there is a query. */\n matches: (item: Value) => boolean;\n /** The value a group's row stands for (`Combobox`); unset, the row is a sentinel. */\n groupToValue?: (group: GroupShape) => Value;\n /** Also tells the sentinel rows apart. */\n isItemEqualToValue: (a: Value, b: Value) => boolean;\n /** Read each time the popup opens: a group it accepts starts folded. */\n startsCollapsed?: (group: GroupShape) => boolean;\n /** The popup mounts open, so `startsCollapsed` applies from the first render. */\n startsOpen?: boolean;\n};\n\n/**\n * Gives each group a row (rendered with `ComboboxGroupHeader`) and collapses groups on request.\n *\n * - The row is the group's first item, so Base UI navigates, filters and presses it.\n * - A collapsed group hands Base UI only its row: Base UI never filters an empty query.\n * - A query opens every group with a match; a fold made under it lasts until the query changes.\n * - A row shows only while its group matches.\n * - Collapse state is keyed by a group's position in `items`.\n */\nexport const useGroupHeaders = <Value, GroupShape extends Group<Value>>({\n items,\n collapsible,\n selectable,\n query,\n matches,\n groupToValue,\n isItemEqualToValue,\n startsCollapsed,\n startsOpen = false,\n}: Options<Value, GroupShape>) => {\n const [collapsedIndexes, setCollapsedIndexes] = useState<ReadonlySet<number>>(() =>\n startsOpen && collapsible && startsCollapsed && isGroupItems<Value, GroupShape>(items)\n ? new Set(items.flatMap((group, index) => (startsCollapsed(group) ? [index] : [])))\n : new Set(),\n );\n const [searchFolds, setSearchFolds] = useState<{ query: string; indexes: ReadonlySet<number> }>({\n query: '',\n indexes: new Set(),\n });\n /** The folds that apply now: those made without a query, or under this very query. */\n const folded: ReadonlySet<number> =\n query === '' ? collapsedIndexes : searchFolds.query === query ? searchFolds.indexes : NO_FOLDS;\n // The query on screen, for a fold that lands after it may have changed.\n const queryRef = useRef(query);\n useLayoutEffect(() => {\n queryRef.current = query;\n }, [query]);\n const highlightedRef = useRef<unknown>(undefined);\n /** The groups animating, and the query their fold belongs to. */\n const [motion, setMotion] = useState<{\n indexes: ReadonlySet<number>;\n folding: boolean;\n scope: string;\n } | null>(null);\n const foldTimerRef = useRef<ReturnType<typeof setTimeout>>(undefined);\n useEffect(() => () => clearTimeout(foldTimerRef.current), []);\n const flip = useGroupFlip(collapsible);\n\n const enabled = (collapsible || selectable) && isGroupItems<Value, GroupShape>(items);\n const headers = new Map<unknown, Header<Value, GroupShape>>();\n\n const listItems = !enabled\n ? items\n : items.map((group, index) => {\n const collapsed = collapsible && folded.has(index);\n const matching = query === '' ? group.items : group.items.filter(matches);\n const row = groupToValue ? groupToValue(group) : createGroupHeaderItem(index);\n headers.set(row, { group, index, collapsed, matching });\n\n return { ...group, items: collapsed ? [row] : [row, ...group.items] };\n });\n\n /**\n * Folds or unfolds groups under `scope`, the query the toggle was made under.\n *\n * - A fold made without a query always lands.\n * - A fold made under a query the input no longer holds is dropped: it would never show.\n */\n const setCollapsed = (indexes: Iterable<number>, collapsed: boolean, scope = query) => {\n const apply = (prev: ReadonlySet<number>) => {\n const next = new Set(prev);\n for (const index of indexes) {\n if (collapsed) next.add(index);\n else next.delete(index);\n }\n return next.size === prev.size && [...next].every((index) => prev.has(index)) ? prev : next;\n };\n if (scope === '') setCollapsedIndexes(apply);\n else if (scope === queryRef.current) {\n setSearchFolds((prev) => {\n const base = prev.query === scope ? prev.indexes : NO_FOLDS;\n const next = apply(base);\n return next === base && prev.query === scope ? prev : { query: scope, indexes: next };\n });\n }\n };\n\n const endMotionAfter = (ms: number, then?: () => void) => {\n clearTimeout(foldTimerRef.current);\n foldTimerRef.current = setTimeout(() => {\n then?.();\n setMotion(null);\n }, ms);\n };\n\n const folding: ReadonlySet<number> = motion?.folding ? motion.indexes : new Set();\n /** A group still fading out counts as folded. */\n const isCollapsed = (index: number) => folded.has(index) || folding.has(index);\n\n /**\n * Unfolds groups with their items animating in, or fades them out, then folds them.\n *\n * - The groups under them slide to their new place.\n * - Folds still fading out finish at once, except those this call unfolds again.\n */\n const animate = (indexes: readonly number[], collapse: boolean, from?: Element | null) => {\n clearTimeout(foldTimerRef.current);\n const animated = hasMotion();\n const finishing = [...folding].filter((index) => collapse || !indexes.includes(index));\n const changing = indexes.filter((index) => isCollapsed(index) !== collapse);\n // Only a layout about to change is worth sliding from.\n if (animated && (finishing.length > 0 || changing.length > 0)) flip.capture(from);\n if (motion) setCollapsed(finishing, true, motion.scope);\n if (!animated || changing.length === 0) {\n setCollapsed(changing, collapse);\n setMotion(null);\n return;\n }\n const scope = query;\n setMotion({ indexes: new Set(changing), folding: collapse, scope });\n if (collapse) endMotionAfter(FOLD_MS, () => setCollapsed(changing, true, scope));\n else {\n setCollapsed(changing, false);\n endMotionAfter(ENTER_MS);\n }\n };\n\n /** Unfolds a folded group, folds an open one. */\n const toggle = (index: number, from?: Element | null) =>\n animate([index], !isCollapsed(index), from);\n\n /** Folds or unfolds every group. */\n const setAllCollapsed = (collapse: boolean, from?: Element | null) => {\n if (!isGroupItems<Value, GroupShape>(items)) return;\n animate(\n items.map((_, index) => index),\n collapse,\n from,\n );\n };\n\n const groupIndexOf = new Map<unknown, number>();\n if (motion && enabled && isGroupItems<Value, GroupShape>(items)) {\n for (const index of motion.indexes) {\n for (const item of items[index]?.items ?? []) groupIndexOf.set(item, index);\n }\n }\n\n const headerOf = (item: unknown) => headers.get(item);\n\n // Rows are rebuilt every render, so fall back to equality for the highlighted row.\n const highlightedHeader = () => {\n const item = highlightedRef.current;\n if (item === undefined) return undefined;\n const header = headers.get(item);\n if (header) return header;\n for (const [row, entry] of headers) {\n if (isItemEqualToValue(row as Value, item as Value)) return entry;\n }\n return undefined;\n };\n\n return {\n enabled,\n /** `items` with group rows added and collapsed groups' items removed. */\n items: listItems,\n collapsible,\n headerOf,\n toggle,\n setAllCollapsed,\n /** `entering` / `leaving` for an item of the group that last unfolded / is folding. */\n motionOf: (item: unknown) => {\n if (!motion || !groupIndexOf.has(item)) return undefined;\n return motion.folding ? 'leaving' : 'entering';\n },\n /** `filter` verdict for a group row (matches while its group does); `undefined` otherwise. */\n filterHeader: (item: unknown) => {\n const header = headerOf(item);\n return header ? header.matching.length > 0 : undefined;\n },\n /** For the root's `onItemHighlighted`: which row the keyboard would toggle. */\n onItemHighlighted: (item: unknown) => {\n highlightedRef.current = item;\n },\n /** For the root's `onOpenChange`: clears the highlight on close, folds `startsCollapsed` on open. */\n onOpenChange: (open: boolean) => {\n if (!open) highlightedRef.current = undefined;\n clearTimeout(foldTimerRef.current);\n if (motion?.folding) setCollapsed(motion.indexes, true, motion.scope);\n setMotion(null);\n if (open && collapsible && startsCollapsed && isGroupItems<Value, GroupShape>(items)) {\n setCollapsedIndexes(\n new Set(items.flatMap((group, index) => (startsCollapsed(group) ? [index] : []))),\n );\n }\n },\n /**\n * For the input's `onKeyDown`: `ArrowRight` / `ArrowLeft` expand / collapse the highlighted row.\n * Only without a query; also stops Base UI moving to the chips.\n */\n onInputKeyDown: (event: BaseUIEvent<KeyboardEvent<HTMLInputElement>>) => {\n if (!collapsible || query !== '') return;\n if (event.key !== 'ArrowRight' && event.key !== 'ArrowLeft') return;\n const header = highlightedHeader();\n if (!header) return;\n\n event.preventDefault();\n event.preventBaseUIHandler();\n if (isCollapsed(header.index) === (event.key === 'ArrowRight')) {\n toggle(header.index, event.currentTarget);\n }\n },\n };\n};\n\nexport type GroupHeaders<Value, GroupShape extends Group<Value>> = ReturnType<\n typeof useGroupHeaders<Value, GroupShape>\n>;\n","import { useEffect } from 'react';\n\nimport { useStableCallback } from '../../hooks/useStableCallback';\nimport { noop } from '../../utils';\n\n/**\n * The text a combobox's input takes, with `inputValueSanitizer` applied to what the user typed.\n *\n * - `input-change` is the only reason carrying typed text. Every other one carries text the\n * control itself put there — an item's label, or the empty string a clear leaves — which a\n * sanitizer aimed at typed characters would mangle.\n * - A sanitizer sees the whole text on every keystroke, so it has to rewrite rather than drop:\n * one calling `trim()` swallows the space before the next word.\n */\nexport const sanitizeTypedInput = (\n next: string,\n reason: string,\n sanitizer: ((input: string) => string) | undefined,\n) => (reason === 'input-change' ? (sanitizer?.(next) ?? next) : next);\n\n/**\n * Reports the query the list filters by to the control's owner.\n *\n * - Fires from an effect rather than the input handler because `query` is derived: in `Combobox`\n * a selection showing its own label empties it without a keystroke, so the handler never sees\n * every value it takes.\n * - The mount render reports too, so an owner fetching on the query needs no first fetch of its\n * own.\n */\nexport const useQueryReporter = (query: string, onQueryChange?: (query: string) => void) => {\n const report = useStableCallback(onQueryChange ?? noop);\n\n useEffect(() => {\n report(query);\n }, [query, report]);\n};\n","import { type ComponentProps, type ReactNode, useCallback, useMemo, useState } from 'react';\nimport { Combobox as BaseCombobox } from '@base-ui/react/combobox';\n\nimport { cn } from '../../utils';\nimport { forwardAccessibleName, type WithAccessibleName } from '../../utils/accessibleName';\nimport { InputGroup } from '../InputGroup';\n\nimport { ComboboxChip } from './ComboboxChip';\nimport { ComboboxChips } from './ComboboxChips';\nimport { ComboboxClearButton } from './ComboboxClearButton';\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 { ComboboxOpenButton } from './ComboboxOpenButton';\nimport { ComboboxOptions } from './ComboboxOptions';\nimport { ComboboxRoot } from './ComboboxRoot';\nimport { ComboboxSeparator } from './ComboboxSeparator';\nimport { useWithCreated } from './createdItems';\nimport { ComboboxCollection, ComboboxGroup, ComboboxGroupLabel } from './Group';\nimport { useGroupHeaders } from './groupHeaders';\nimport { useQueryReporter } from './query';\nimport type { Group } from './types';\nimport {\n createCreatableItem,\n defaultGroupToLabel,\n defaultItemToDisabled,\n defaultItemToIcon,\n defaultQueryToCreateLabel,\n defaultRowLabel,\n defaultToCreateValue,\n flatItems,\n isCreatableItem,\n isGroupHeaderItem,\n toEntries,\n toLabel,\n useCreatableStringValue,\n useItemEquality,\n} from './utils';\nimport { useVirtualList, type VirtualizedProps } from './virtualList';\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 = Exclude<NonNullable<ComboboxItemProps['indicator']>, 'none'>;\n\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.\ntype PublicComboboxInputProps = Pick<\n ComboboxInputProps,\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, 'focusVariant' | '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`; `false` hides the create row.\n * - Called only for a non-empty query that matches no existing item.\n */\n canCreate?: (query: string) => boolean;\n};\n\ntype BaseProps<Value, GroupShape extends Group<Value> = Group<Value>> = PublicComboboxInputProps &\n PublicComboboxProps<Value> &\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 /** `false` where clearing must be unreachable, e.g. a required field. */\n allowClear?: boolean;\n empty?: ReactNode;\n /**\n * The options are still arriving — a request for `items` is in flight.\n *\n * - Does not disable the control; pass `disabled` too where the user has to wait.\n */\n isLoading?: boolean;\n indicator?: Indicator;\n prefix?: ReactNode;\n\n /**\n * Rewrites typed text (not the selected label); filter and `allowCreate` see the result.\n * - Rewrite, don't drop: it sees the whole text per keystroke, so `trim()` eats word spaces.\n */\n inputValueSanitizer?: (input: string) => string;\n /**\n * Reports the sanitized query, also on mount; empty while the input shows the selection.\n * - Notification only: the control owns the input text; there is no controlled `inputValue`.\n */\n onQueryChange?: (query: string) => void;\n\n /** Row content, `itemToStringLabel` by default; pass `query` to `MarkedText` to mark a match. */\n itemToLabel?: (item: Value, query: string) => ReactNode;\n itemToIcon?: (item: Value) => ReactNode;\n itemToDisabled?: (item: Value) => boolean;\n /**\n * Selection node drawn over the transparent input while closed; typing dissolves it. Clipped.\n * - Decoration: the input keeps `itemToStringLabel` text for screen readers, unlike `prefix`.\n */\n itemToSelectedLabel?: (item: Value) => ReactNode;\n\n /** Defaults to the group's `label`, as `Select` shows it. */\n groupToLabel?: (group: GroupShape) => ReactNode;\n /**\n * Each group gets a toggle row; with `groupToValue`, only the chevron and ←/→ keys toggle it.\n * - A query shows all matches regardless of collapse and hides groups without one.\n */\n collapsibleGroups?: boolean;\n /**\n * Makes each group's row selectable as the returned value.\n * - `itemToStringLabel`, `itemToSelectedLabel` and `itemToDisabled` then receive it too.\n */\n groupToValue?: (group: GroupShape) => Value;\n };\n\ntype Props<Value, GroupShape extends Group<Value> = Group<Value>> = WithAccessibleName<\n BaseProps<Value, GroupShape>\n>;\n\nconst acceptAll = () => true;\nconst NO_ITEMS: readonly never[] = [];\n\nexport const Combobox = <Value, GroupShape extends Group<Value> = Group<Value>>({\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 focusVariant,\n state,\n placeholder,\n allowClear = true,\n name,\n onBlur,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n className,\n\n empty = 'No items',\n isLoading = false,\n indicator,\n prefix,\n virtualized = false,\n\n inputValueSanitizer,\n onQueryChange,\n\n allowCreate,\n queryToCreateValue,\n queryToCreateLabel = defaultQueryToCreateLabel,\n canCreate,\n\n itemToDisabled = defaultItemToDisabled,\n itemToLabel: itemToLabelProp,\n itemToIcon = defaultItemToIcon,\n itemToSelectedLabel,\n groupToLabel = defaultGroupToLabel,\n collapsibleGroups = false,\n groupToValue,\n ...accessibleName\n}: Props<Value, GroupShape>) => {\n /** An item's string identity: input text, default search subject, accessible value. */\n const labelOf = useCallback(\n (item: Value) => itemToStringLabelProp?.(item) ?? toLabel(item),\n [itemToStringLabelProp],\n );\n const itemToLabel = itemToLabelProp ?? defaultRowLabel(itemToStringLabelProp);\n\n // What the user typed, or `null` while the control shows its selection.\n // - Input text and query both derive from it.\n // - Reset on close here: Base UI's sync-back skips text already equal to the label.\n const [typedText, setTypedText] = useState<string | null>(null);\n\n // The held item, controlled or not; mirrored from Base UI while uncontrolled.\n // - `null` is both \"nothing selected\" and the adder shape's pinned value.\n // - Read here, not via `BaseCombobox.Value`: the query gate and two classNames need it.\n const [uncontrolledValue, setUncontrolledValue] = useState<Value | null>(defaultValue ?? null);\n const selectedItem = value !== undefined ? value : uncontrolledValue;\n\n const selectedLabel = selectedItem == null ? null : labelOf(selectedItem);\n\n // Whether the on-screen text is the selection rather than a query.\n // - Compares with the label, not `null`: a query edited back to the label reads the same.\n const isShowingSelection =\n selectedLabel !== null && (typedText === null || typedText === selectedLabel);\n\n // The query, else the selection's label, which is what a screen reader reports.\n const inputValue = typedText ?? selectedLabel ?? '';\n // Shown only while the input's text is still the selection's label.\n const selectedNode =\n itemToSelectedLabel && selectedItem != null && isShowingSelection\n ? itemToSelectedLabel(selectedItem)\n : null;\n const query = (isShowingSelection ? '' : (typedText ?? '')).trim();\n const queryLower = query.toLowerCase();\n\n useQueryReporter(query, onQueryChange);\n\n // `aria-busy` for the input alone, absent rather than `false` while nothing is loading.\n //\n // - Not on the list: assistive tech may hold back a busy subtree, and the items already listed\n // stay pickable while loading. The empty slot's live region announces \"Loading…\" instead.\n const busy = isLoading || undefined;\n\n const itemsProp = _itemsProp ?? NO_ITEMS;\n const sampleItem = flatItems(itemsProp)[0];\n\n const isItemEqualToValue = useItemEquality(isItemEqualToValueProp);\n\n // The one value `allowCreate` minted, listed while it is the selection and `items` lacks it.\n // - An adder pinned to `null` lists none; `items` is scanned only when it or the value changes.\n const [createdItems, setCreatedItems] = useState<Value[]>([]);\n const [createdItem] = createdItems;\n const itemsHoldCreated = useMemo(\n () =>\n createdItem !== undefined &&\n flatItems(itemsProp).some((listed) => isItemEqualToValue(listed, createdItem)),\n [createdItem, itemsProp, isItemEqualToValue],\n );\n const created =\n createdItem !== undefined &&\n !itemsHoldCreated &&\n selectedItem != null &&\n isItemEqualToValue(createdItem, selectedItem)\n ? createdItems\n : NO_ITEMS;\n\n // Stable while the caller's accessor is: Base UI re-filters on every new identity.\n const itemToStringLabel = useCallback<NonNullable<ComboboxProps<Value>['itemToStringLabel']>>(\n (value) => {\n if (isCreatableItem(value)) return value.value;\n if (isGroupHeaderItem(value)) return value.label;\n return labelOf(value);\n },\n [labelOf],\n );\n\n const { contains } = BaseCombobox.useFilter();\n const itemFilter = filter ?? contains;\n const groupHeaders = useGroupHeaders<Value, GroupShape>({\n items: itemsProp,\n collapsible: collapsibleGroups,\n selectable: groupToValue !== undefined,\n query,\n matches: (item) => itemFilter(item, query, itemToStringLabel),\n groupToValue,\n isItemEqualToValue,\n });\n\n const allItems = useWithCreated(itemsProp, created);\n // What the list shows: `allItems` with each group's own row, once `groupHeaders` adds them.\n const listItems = useWithCreated(groupHeaders.items, created);\n\n const showCreateRow = (() => {\n if (!allowCreate || disabled || !query) return false;\n const exactMatch = flatItems(allItems).some(\n (item) => labelOf(item).toLowerCase() === queryLower,\n );\n return !exactMatch && (!canCreate || canCreate(query));\n })();\n\n const items = useMemo(\n () =>\n showCreateRow\n ? [...listItems, ...toEntries(listItems, [createCreatableItem(query)])]\n : listItems,\n [showCreateRow, listItems, query],\n );\n\n // Behind a selection the whole list stays browsable instead of narrowing to that item.\n // - Base UI's `shouldBypassFiltering` covers only a fresh open, not text edited back to the label.\n // - Creatable and group rows bypass the caller's `filter`; a group row matches while a child does.\n const filterHeader = groupHeaders.enabled ? groupHeaders.filterHeader : undefined;\n const queryFilter = useMemo<ComboboxProps<Value>['filter']>(() => {\n if (filterHeader) {\n return (item, query, itemToString) =>\n filterHeader(item) ?? (isCreatableItem(item) || itemFilter(item, query, itemToString));\n }\n if (!allowCreate || !filter) return filter;\n return (item, query, itemToString) =>\n isCreatableItem(item) || filter(item, query, itemToString);\n }, [filterHeader, allowCreate, filter, itemFilter]);\n const wrappedFilter = isShowingSelection ? acceptAll : queryFilter;\n\n const wrappedItemToStringValue = useCreatableStringValue(itemToStringValue, allowCreate);\n\n // Only user typing becomes `typedText` and passes through `inputValueSanitizer`.\n // - Every other reason (item press, clear, unmount sync-back) means \"show the selection\".\n // - The sync-back is never adopted: for a created item it stringifies the internal sentinel.\n const handleInputValueChange: NonNullable<ComboboxProps<Value>['onInputValueChange']> = (\n next,\n { reason },\n ) => {\n if (reason !== 'input-change') {\n setTypedText(null);\n return;\n }\n\n const typed = inputValueSanitizer?.(next) ?? next;\n // Whitespace-only text is dropped: Base UI won't open on it, so no close would discard it.\n // An empty input clears the selection, so it is adopted.\n setTypedText(typed === '' || typed.trim() !== '' ? typed : null);\n };\n\n // Discard the query as the popup starts closing, not after its transition.\n const handleOpenChange: NonNullable<ComboboxProps<Value>['onOpenChange']> = (open) => {\n if (!open) setTypedText(null);\n groupHeaders.onOpenChange(open);\n };\n\n const handleOnValueChange: ComboboxProps<Value>['onValueChange'] = (next, event) => {\n if (isCreatableItem(next)) {\n const newValue = defaultToCreateValue(next.value, sampleItem, queryToCreateValue) as Value;\n setCreatedItems([newValue]);\n setUncontrolledValue(newValue);\n onValueChange?.(newValue, event);\n return;\n }\n\n setUncontrolledValue(next);\n onValueChange?.(next, event);\n };\n\n // Decided on the real options rather than `items`, whose transient create row would switch\n // windowing on and off as the user types.\n const virtualList = useVirtualList(allItems, virtualized);\n\n const comboboxInput = (\n <ComboboxInput\n {...forwardAccessibleName(accessibleName)}\n name={name}\n onBlur={onBlur}\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 // Text stays for screen readers and the caret; `selectedNode` is drawn over it.\n className={cn(\n selectedNode != null &&\n 'tw:text-transparent tw:caret-foreground tw:selection:bg-transparent',\n )}\n />\n );\n\n return (\n <BaseCombobox.Root<Value, false>\n items={items}\n // Otherwise Enter after typing drops the query; this commits the first match or create row.\n autoHighlight\n value={value}\n defaultValue={defaultValue}\n filter={wrappedFilter}\n onValueChange={handleOnValueChange}\n itemToStringLabel={itemToStringLabel}\n isItemEqualToValue={isItemEqualToValue}\n itemToStringValue={wrappedItemToStringValue}\n onOpenChange={handleOpenChange}\n onOpenChangeComplete={onOpenChangeComplete}\n disabled={disabled}\n inputRef={inputRef}\n inputValue={inputValue}\n onInputValueChange={handleInputValueChange}\n virtualized={virtualList.enabled}\n onItemHighlighted={(item, details) => {\n groupHeaders.onItemHighlighted(item);\n virtualList.onItemHighlighted(details);\n }}\n >\n <ComboboxInputGroup state={state} focusVariant={focusVariant} className={className}>\n {itemToSelectedLabel != null ? (\n // The addon overlays the input inside a `relative` wrapper; its `pl-4` and the input's\n // `px-4` share one origin.\n // - Branch on the prop, not `selectedNode`: swapping trees mid-typing drops input focus.\n <div className=\"tw:relative tw:flex tw:min-w-0 tw:flex-1\">\n {(prefix != null || selectedNode != null) && (\n <InputGroup.Addon\n align=\"inline-start\"\n className={cn(\n selectedNode != null &&\n 'tw:pointer-events-none tw:absolute tw:inset-y-0 tw:left-0 tw:max-w-full tw:overflow-hidden',\n )}\n >\n {prefix}\n {selectedNode}\n </InputGroup.Addon>\n )}\n {comboboxInput}\n </div>\n ) : (\n <>\n {prefix != null && <InputGroup.Addon align=\"inline-start\">{prefix}</InputGroup.Addon>}\n {comboboxInput}\n </>\n )}\n <InputGroup.Addon align=\"inline-end\">\n {allowClear && <ComboboxClearButton disabled={disabled} />}\n <ComboboxOpenButton disabled={disabled} isLoading={isLoading} />\n </InputGroup.Addon>\n </ComboboxInputGroup>\n <ComboboxContent>\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 createLabel={queryToCreateLabel}\n groupRowState={\n groupToValue\n ? (row) => ({\n checked: selectedItem != null && isItemEqualToValue(row, selectedItem),\n disabled: itemToDisabled(row),\n })\n : undefined\n }\n />\n </ComboboxContent>\n </BaseCombobox.Root>\n );\n};\n\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\nCombobox.Group = ComboboxGroup;\nCombobox.GroupLabel = ComboboxGroupLabel;\nCombobox.GroupList = ComboboxCollection;\n\nCombobox.Chips = ComboboxChips;\nCombobox.Chip = ComboboxChip;\n","import { toLabel } from './utils';\n\n/** A single searchable text. `null` / `undefined` / `''` stand for \"this item has no such field\". */\ntype Text = string | number | null | undefined;\n\n// Lowercased words of a query.\n//\n// - Splits on whitespace runs, so no empty word matches every text.\n// - Plain `toLowerCase`: `foldCase` only matters for offsets, and none are reported here.\nconst toWords = (query: string) => query.toLowerCase().split(/\\s+/).filter(Boolean);\n\nconst isFilled = (text: Text): text is string | number =>\n text !== null && text !== undefined && text !== '';\n\nconst isTextList = (texts: Text | readonly Text[]): texts is readonly Text[] =>\n Array.isArray(texts);\n\n/**\n * Whether every word of `query` occurs in some of `texts`, ignoring case.\n *\n * - Words match by containment, across texts, in any order; an empty query matches everything.\n * - Plain lowercased `includes`, not `Intl.Collator`: `Muller` does not find `Müller`.\n * - Not interchangeable with kbc-ui's own `matchByWords` (single-space split, keeps empty texts).\n * - A `filter` for when the searchable text is not the label; else use {@link filterByWords}.\n */\nexport const matchByWords = (texts: Text | readonly Text[], query: string) => {\n const words = toWords(query);\n if (words.length === 0) return true;\n\n const haystacks = (isTextList(texts) ? texts : [texts])\n .filter(isFilled)\n .map((text) => String(text).toLowerCase());\n\n return words.every((word) => haystacks.some((haystack) => haystack.includes(word)));\n};\n\n/**\n * `filter` matching the item's displayed label word by word: `filter={filterByWords}`.\n *\n * - Generic, so it keeps the combobox's item type inference.\n * - Label: `itemToStringLabel` if passed, else the item's `label`, `value`, or string form.\n * - Only the label is searched, by design: never match what the user cannot see.\n * - Close over {@link matchByWords} to search other fields.\n */\nexport const filterByWords = <Item>(\n item: Item,\n query: string,\n itemToString?: (item: Item) => string,\n) => matchByWords(itemToString?.(item) ?? toLabel(item), query);\n"],"mappings":"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"}
1
+ {"version":3,"file":"Combobox-RZ0i3w8u.js","names":["BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","Combobox","BaseCombobox"],"sources":["../src/components/Combobox/blankValues.ts","../src/components/Combobox/ComboboxChip.tsx","../src/components/Combobox/utils.ts","../src/components/Combobox/ComboboxChips.tsx","../src/components/Combobox/ComboboxClearButton.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/virtualList.ts","../src/components/Combobox/ComboboxItem.tsx","../src/components/Combobox/ComboboxList.tsx","../src/components/Combobox/ComboboxOpenButton.tsx","../src/components/Combobox/Group/ComboboxGroupHeader.tsx","../src/components/Combobox/Group/ComboboxGroup.tsx","../src/components/Combobox/Group/ComboboxGroupLabel.tsx","../src/components/Combobox/Group/ComboboxCollection.tsx","../src/components/Combobox/ComboboxFullList.tsx","../src/components/Combobox/ComboboxLoadingEmpty.tsx","../src/components/Combobox/ComboboxVirtualList.tsx","../src/components/Combobox/ComboboxOptions.tsx","../src/components/Combobox/ComboboxRoot.tsx","../src/components/Combobox/ComboboxSeparator.tsx","../src/components/Combobox/createdItems.ts","../src/components/Combobox/groupFlip.ts","../src/components/Combobox/groupHeaders.ts","../src/components/Combobox/query.ts","../src/components/Combobox/Combobox.tsx","../src/components/Combobox/matchByWords.ts"],"sourcesContent":["/**\n * The two blank strings a Storage filter predicates on, in list order.\n *\n * - Hand it to `items` where the blanks are the whole list — a value field whose other entries the\n * user types. {@link withBlankValues} is for offering them ahead of a list that already exists.\n */\nexport const BLANK_VALUES: readonly string[] = ['', ' '];\n\nconst BLANK_LABELS: Record<string, string> = {\n '': '[empty string]',\n ' ': '[space character]',\n};\n\n/**\n * A string as a row or a chip shows it — named when its text is blank, itself otherwise.\n *\n * - Exported so an `itemToLabel` / `itemToChipLabel` / `itemToSelectedLabel` / `renderChips`\n * override can keep the default naming instead of retyping the labels.\n * - The two blank values get their own labels; any other whitespace-only string (a tab, a run of\n * spaces) falls back to a generic one, so two different ones read alike.\n * - Identity is unaffected — `toLabel` keys items off the raw string.\n */\nexport const namedLabel = (text: string): string =>\n text.trim() === '' ? (BLANK_LABELS[text] ?? '[whitespace]') : text;\n\n/**\n * `values` with both blank values offered ahead of them, and duplicates collapsed.\n *\n * - The dedupe matters where the list is the distinct values of a Storage column: it can already\n * hold a blank, and two `Object.is`-equal rows both report `aria-selected` and toggle each other.\n * - First occurrence wins, so the order of the values is otherwise preserved.\n * - String items only — the seven Storage filters this serves are all string-valued.\n */\nexport const withBlankValues = (values: readonly string[]): string[] => [\n ...new Set([...BLANK_VALUES, ...values]),\n];\n","import { type ComponentProps, type KeyboardEvent, type ReactNode, useState } from 'react';\nimport { Combobox as BaseCombobox } from '@base-ui/react/combobox';\n\nimport { X } from '../../icons';\nimport { Badge } from '../Badge';\nimport { Tooltip, TooltipProvider } from '../Tooltip';\nimport { hasTruncationOverflow } from '../Truncated';\n\nexport type BadgeColor = ComponentProps<typeof Badge>['color'];\nexport type BadgeVariant = ComponentProps<typeof Badge>['variant'];\n\n/**\n * Keeps a chip's keyboard handling off its content's.\n *\n * - Base UI's chip `preventDefault`s Enter/Space, cancelling a nested link or button.\n * - Capture phase, so the chip's own bubble handler never runs.\n * - Target-guarded, so the chip's own keys (Backspace, Delete, arrows) still reach it.\n */\nconst stopNestedKeyDown = (event: KeyboardEvent<HTMLElement>) => {\n if (event.target !== event.currentTarget) event.stopPropagation();\n};\n\ntype Props = {\n children: ReactNode;\n color?: BadgeColor;\n variant?: BadgeVariant;\n};\n\n/**\n * One removable chip in a `MultiCombobox`'s `renderChips` slot or `Combobox.Chips`.\n *\n * - Position is identity: Base UI removes by index, so render one per `value` entry, in order.\n * - A non-removable chip is a plain `Badge`: a chip would shift the removal index.\n * - A label cut off by the chip's width shows in full in a tooltip on hover.\n */\nexport const ComboboxChip = ({ children, color, variant }: Props) => {\n const [isTruncated, setIsTruncated] = useState(false);\n\n return (\n <BaseCombobox.Chip\n render={<Badge.Root color={color} variant={variant ?? 'pill'} className=\"tw:max-w-40\" />}\n onKeyDownCapture={stopNestedKeyDown}\n >\n <TooltipProvider>\n <Tooltip tooltip={children} forceHide={!isTruncated} placement=\"top\" triggerAsChild>\n {/* The trigger's `tailwindcss-preflight` sets `line-height: 1.5`; keep the badge's own. */}\n <Badge.Label\n className=\"tw:leading-[inherit]\"\n onMouseOver={(event) => setIsTruncated(hasTruncationOverflow(event.currentTarget))}\n >\n {children}\n </Badge.Label>\n </Tooltip>\n </TooltipProvider>\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","import { isValidElement, type ReactNode, useMemo } from 'react';\n\nimport { namedLabel } from './blankValues';\nimport type {\n CreatableItem,\n Group,\n GroupHeaderItem,\n InternalItems,\n LabeledItem,\n SelectAllItem,\n} 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\nconst isLabeledItem = (item: unknown): item is LabeledItem =>\n isPlainObject(item) && Reflect.has(item, 'label') && Reflect.has(item, 'value');\n\nexport const 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 isGroupHeaderItem = (item: unknown): item is GroupHeaderItem =>\n isInternalItem(item) && item.__marker === 'groupHeader';\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 empty as non-grouped\n return isGroupItem(items[0]); // Base UI checks only the first item\n};\n\n/** The options of a list, its groups flattened. */\nexport const flatItems = <Value>(list: readonly (Value | Group<Value>)[]) => {\n const items: Value[] = [];\n for (const entry of list) {\n if (!isGroupItem(entry)) items.push(entry);\n // One push per item: spreading a large group would exceed the engine's argument limit.\n else for (const item of entry.items) items.push(item);\n }\n return items;\n};\n\n/** The create row and Select All: each is drawn outside any group, even in a grouped list. */\nexport const isLooseItem = (item: unknown): item is CreatableItem | SelectAllItem =>\n isCreatableItem(item) || isSelectAllItem(item);\n\n/**\n * `items` as entries of `list`: one group without a label in a grouped list, else themselves.\n *\n * - Base UI reads the first entry to tell a grouped list, so every entry has to match it.\n * - The group never reaches `groupToLabel`: {@link isEntriesGroup} tells it apart.\n */\nexport const toEntries = <Item>(list: readonly unknown[], items: readonly Item[]) =>\n isGroupItems(list) ? [{ __marker: 'entries' as const, items }] : items;\n\n/** A group {@link toEntries} made; Base UI's filter keeps the marker, as it spreads each group. */\nexport const isEntriesGroup = (entry: unknown) =>\n isGroupItem(entry) && Reflect.get(entry, '__marker') === 'entries';\n\n/**\n * Node a list row and a chip show for an item.\n *\n * - Names a blank string, so a row or chip never renders as nothing; {@link toLabel} does not.\n * - A non-string `label` (a JSX node) passes through.\n */\nexport const defaultItemToLabel = <Item>(item: Item) => {\n if (isNumber(item)) return item;\n if (isString(item)) return namedLabel(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 isString(item.label) ? namedLabel(item.label) : item.label;\n};\n\n/**\n * The node a row or a chip shows for an item when the caller passes no `itemToLabel`.\n *\n * - Names a blank `itemToStringLabel` result, which would otherwise render as nothing.\n * - Falls back to the item's own string: Base UI reports the outgoing selection for one render\n * after `items` and `itemToStringLabel` change together.\n */\nexport const defaultRowLabel = <Item>(itemToStringLabel?: (item: Item) => string) =>\n itemToStringLabel\n ? (item: Item) => namedLabel(itemToStringLabel(item) ?? toLabel(item))\n : defaultItemToLabel;\n\n/**\n * Display string for an item — mirrors Base UI's default.\n *\n * - Also the default search text and the closed `Combobox`'s input value.\n * - Does not name blank strings: `''` may mean \"nothing selected\", and must keep the placeholder.\n * - A labelled item with neither a label nor a value reads as `''`, like the string item `''`.\n * - Naming lives in {@link defaultItemToLabel}, read only by rows and chips.\n */\nexport const toLabel = (item: unknown): string => {\n if (isString(item)) return item;\n if (isLabeledItem(item)) return item.label || item.value || '';\n return String(item);\n};\n\n/** Equality key for an item — prefers `.value`. */\nconst toValueKey = (item: unknown): string => {\n if (isString(item)) return item;\n if (isLabeledItem(item)) return item.value || item.label || '';\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\n/** A group's `label`, as `Select` renders it; one that is not a node reads as none. */\nexport const defaultGroupToLabel = (group: object): ReactNode => {\n const label: unknown = Reflect.get(group, 'label');\n return isString(label) || isNumber(label) || isValidElement(label) ? label : undefined;\n};\n\n// Internal markers: LabeledItem-shaped sentinels injected into Base UI's items.\n// - `__marker` keeps consumer items and callbacks from colliding with them.\n\nexport const selectAllItem: SelectAllItem = {\n __marker: 'selectAll',\n value: '__select_all__',\n label: 'Select All',\n};\n\n/** Row for the group at `index` — keyed by position, like its collapse state. */\nexport const createGroupHeaderItem = (index: number): GroupHeaderItem => ({\n __marker: 'groupHeader',\n value: `__group_${index}__`,\n label: '',\n});\n\nexport const createCreatableItem = (query: string): CreatableItem => ({\n __marker: 'creatable',\n value: query,\n label: query,\n});\n\n/**\n * Item-equality predicate for a Base UI combobox root.\n *\n * - A sentinel equals a sentinel by marker and value key (the create row is rebuilt per keystroke).\n * - A sentinel never equals a real item.\n * - Real items use the caller's predicate, else `Object.is`.\n */\nexport const toItemEquality =\n <Value>(isItemEqualToValue?: (a: Value, b: Value) => boolean) =>\n (a: Value, b: Value) => {\n if (isInternalItem(a) || isInternalItem(b)) {\n return (\n isInternalItem(a) &&\n isInternalItem(b) &&\n a.__marker === b.__marker &&\n toValueKey(a) === toValueKey(b)\n );\n }\n return isItemEqualToValue?.(a, b) ?? Object.is(a, b);\n };\n\n/**\n * {@link toItemEquality} with a stable identity.\n *\n * - Base UI lists the comparer in an effect's deps; a new one per render re-renders every row.\n */\nexport const useItemEquality = <Value>(isItemEqualToValue?: (a: Value, b: Value) => boolean) =>\n useMemo(() => toItemEquality(isItemEqualToValue), [isItemEqualToValue]);\n\n/** `itemToStringValue` that also reads the create row, whose value is its query. */\nexport const withCreatableStringValue = <Value>(\n itemToStringValue: ((item: Value) => string) | undefined,\n allowCreate: boolean | undefined,\n) =>\n !allowCreate || !itemToStringValue\n ? itemToStringValue\n : (item: Value) => (isCreatableItem(item) ? item.value : itemToStringValue(item));\n\n/** {@link withCreatableStringValue} with a stable identity. */\nexport const useCreatableStringValue = <Value>(\n itemToStringValue: ((item: Value) => string) | undefined,\n allowCreate: boolean | undefined,\n) =>\n useMemo(\n () => withCreatableStringValue(itemToStringValue, allowCreate),\n [itemToStringValue, allowCreate],\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 { ReactNode } from 'react';\nimport { Combobox as BaseCombobox } from '@base-ui/react/combobox';\n\nimport { Badge } from '../Badge';\n\nimport { type BadgeColor, type BadgeVariant, ComboboxChip } from './ComboboxChip';\nimport { defaultItemToLabel, isInternalItem } from './utils';\n\ntype Props<Value> = {\n maxVisible?: number;\n itemToChipLabel?: (item: Value) => ReactNode;\n itemToChipColor?: (item: Value) => BadgeColor;\n /**\n * Non-removable chips ahead of the values, outside `maxVisible` and absent from `value`.\n */\n pinnedChipLabels?: ReactNode[];\n variant?: BadgeVariant;\n /**\n * Renders the chip area in place of the default chips; every other prop is then unused.\n */\n children?: (values: Value[]) => ReactNode;\n};\n\nexport const ComboboxChips = <Value,>({\n maxVisible = 3,\n itemToChipLabel = defaultItemToLabel,\n itemToChipColor,\n pinnedChipLabels,\n variant = 'pill',\n children,\n}: Props<Value>) => (\n <BaseCombobox.Value>\n {(rawValues: Value[]) => {\n // Drop the Select All marker Base UI keeps in `value`: it gets no chip and never reaches\n // the caller's `itemToChipLabel` / `itemToChipColor`.\n const values = rawValues.filter((value) => !isInternalItem(value));\n\n if (children) return children(values);\n\n const visible = values.slice(0, maxVisible);\n const overflow = values.slice(maxVisible);\n\n return (\n <>\n {pinnedChipLabels?.map((label, index) => (\n // oxlint-disable-next-line react/no-array-index-key\n <Badge key={index} className=\"tw:max-w-40\" variant={variant}>\n {label}\n </Badge>\n ))}\n\n {visible.map((value: Value, index) => (\n <ComboboxChip\n // oxlint-disable-next-line react/no-array-index-key\n key={index}\n color={itemToChipColor?.(value)}\n variant={variant}\n >\n {itemToChipLabel(value)}\n </ComboboxChip>\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 { Combobox as BaseCombobox } from '@base-ui/react/combobox';\n\nimport { X } from '../../icons';\nimport { InputGroup } from '../InputGroup';\n\ntype Props = {\n disabled?: boolean;\n};\n\n/** The button that clears the selection. */\nexport const ComboboxClearButton = ({ disabled }: Props) => (\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","import type { ComponentProps } from 'react';\nimport { Combobox as BaseCombobox } from '@base-ui/react/combobox';\nimport { DismissableLayer } from '@radix-ui/react-dismissable-layer';\n\nimport { cn } from '../../utils';\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 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 return (\n <BaseCombobox.Portal container={container}>\n {/*\n * Registers the popup in Radix's layer stack.\n *\n * - Base UI portals the popup out of the DOM, so a surrounding Radix `Modal` / `Sheet` /\n * `Popover` would otherwise still count itself as topmost and close on Escape. Radix reads\n * the key off a document capture listener, so being a higher layer is the only lever.\n * - No `onDismiss`: Base UI closes the popup itself, the layer only claims the keystroke.\n */}\n <DismissableLayer asChild>\n <BaseCombobox.Positioner\n align={align}\n side={side}\n sideOffset={sideOffset}\n alignOffset={alignOffset}\n anchor={anchor}\n className=\"tw:isolate tw:z-overlay tailwindcss-preflight\"\n >\n <BaseCombobox.Popup\n ref={ref}\n data-slot=\"combobox-content\"\n data-chips={!!anchor}\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\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 </DismissableLayer>\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 type { WithAccessibleName } from '../../utils/accessibleName';\nimport { InputGroup } from '../InputGroup';\n\n/** The input carries the `combobox` role, so the name is required here, not on the group. */\ntype Props = WithAccessibleName<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<ComponentProps<typeof InputGroup>, 'focusVariant' | 'state'>;\n\ntype Props = InputGroupProps &\n Omit<ComponentProps<typeof BaseCombobox.InputGroup>, 'render' | 'className'> & {\n className?: string;\n };\n\nexport const ComboboxInputGroup = ({ ref, state, focusVariant, className, ...props }: Props) => (\n <BaseCombobox.InputGroup\n {...props}\n ref={ref}\n render={<InputGroup state={state} focusVariant={focusVariant} className={className} />}\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 // `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-hover-foreground',\n className,\n )}\n render={<Check />}\n />\n );\n};\n","import { createContext, useRef } from 'react';\n\nimport { isGroupItems } from './utils';\n\n/** Above this many options, `virtualized=\"auto\"` windows the list. */\nconst VIRTUALIZE_THRESHOLD = 30;\n\nexport type VirtualizedProps = {\n /** Puts only the rows in view into the DOM: `'auto'` past 30 options, grouped or not; `true` always. */\n virtualized?: boolean | 'auto';\n};\n\n/** Scrolls the option at Base UI's flat `index` into view, unless it is in view already. */\nexport type VirtualListHandle = { scrollToItem: (index: number) => void };\n\n/**\n * The position a windowed list gives each option it renders.\n *\n * - `index` is the option's place in Base UI's flat filtered list, which keyboard navigation counts.\n * - `aria-setsize` / `aria-posinset` keep the set's length known while most options are out of the DOM.\n * - `undefined` outside a windowed list, so a fully rendered list keeps its markup.\n */\nexport const VirtualRowContext = createContext<\n { index: number; 'aria-setsize': number; 'aria-posinset': number } | undefined\n>(undefined);\n\n/**\n * Whether a combobox windows its list, and what ties Base UI's highlight to the window.\n *\n * - `'auto'` counts options, not groups, so a list of a few large groups windows too.\n * - `onItemHighlighted` scrolls a row the keyboard reached into view; a pointer is over its row.\n * - `ref` goes to `ComboboxVirtualList`.\n */\nexport const useVirtualList = (\n items: readonly unknown[],\n virtualized: NonNullable<VirtualizedProps['virtualized']>,\n) => {\n const ref = useRef<VirtualListHandle>(null);\n const count = isGroupItems(items)\n ? items.reduce((sum, group) => sum + group.items.length, 0)\n : items.length;\n\n return {\n enabled: virtualized === 'auto' ? count > VIRTUALIZE_THRESHOLD : virtualized,\n ref,\n onItemHighlighted: ({ reason, index }: { reason: string; index: number }) => {\n if (reason !== 'pointer') ref.current?.scrollToItem(index);\n },\n };\n};\n","import { type ComponentProps, type ReactNode, use } from 'react';\nimport { Combobox as BaseCombobox } from '@base-ui/react/combobox';\n\nimport { cn } from '../../utils';\n\nimport { ComboboxItemIndicator } from './ComboboxItemIndicator';\nimport { VirtualRowContext } from './virtualList';\n\ntype Props = Omit<ComponentProps<typeof BaseCombobox.Item>, 'className'> & {\n className?: string;\n icon?: ReactNode;\n /** `'none'` leaves the row without one — a row that draws its own state in `icon`. */\n indicator?: ComponentProps<typeof ComboboxItemIndicator>['variant'] | 'none';\n /** Looks disabled but still takes the highlight; the owning control ignores its presses. */\n locked?: boolean;\n};\n\nexport const ComboboxItem = ({\n ref,\n className,\n children,\n icon,\n indicator: variant = 'check',\n locked,\n ...props\n}: Props) => (\n <BaseCombobox.Item\n {...props}\n {...use(VirtualRowContext)}\n ref={ref}\n data-slot=\"combobox-item\"\n data-locked={locked || undefined}\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:rounded-lg',\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-hover',\n 'tw:data-[highlighted]:text-hover-foreground',\n\n // disabled\n 'tw:data-disabled:pointer-events-none',\n 'tw:data-disabled:opacity-disabled',\n 'tw:data-locked:opacity-disabled',\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 {variant !== 'none' && <ComboboxItemIndicator variant={variant} />}\n {icon}\n {/* Wraps rather than truncates; fills the row so a label can push content to its end. */}\n {/* `data-slot`: a host aligning the leading marks to the label's first line targets it. */}\n <span data-slot=\"combobox-item-label\" className=\"tw:min-w-0 tw:flex-1 tw:wrap-anywhere\">\n {children}\n </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 className,\n )}\n {...props}\n />\n);\n","import { Combobox as BaseCombobox } from '@base-ui/react/combobox';\n\nimport { ChevronDown, Loader2 } from '../../icons';\nimport { InputGroup } from '../InputGroup';\n\ntype Props = {\n disabled?: boolean;\n isLoading: boolean;\n};\n\n/**\n * The button that opens the popup: a chevron, or a spinner while the options are loading.\n *\n * - The spinner swaps in for the icon inside the one button, which costs the control no width, so\n * the input keeps its room whether or not a request is in flight.\n * - The button keeps opening the popup while loading, so a list that already has items stays\n * reachable.\n */\nexport const ComboboxOpenButton = ({ disabled, isLoading }: Props) => (\n <InputGroup.Button disabled={disabled} asChild aria-label=\"Open combobox\">\n <BaseCombobox.Trigger>\n {isLoading ? (\n <Loader2 className=\"tw:size-4 tw:animate-spin\" />\n ) : (\n <ChevronDown className=\"tw:size-4\" />\n )}\n </BaseCombobox.Trigger>\n </InputGroup.Button>\n);\n","import type { MouseEvent, ReactNode } from 'react';\n\nimport { Check, ChevronRight, Minus } from '../../../icons';\nimport { cn } from '../../../utils';\nimport { isToggleAllClick } from '../../Tooltip/toggleAll';\nimport { ToggleAllTooltip } from '../../Tooltip/ToggleAllTooltip';\nimport { ComboboxItem } from '../ComboboxItem';\n\n/** Indent of a header's children (chevron + gap). */\nexport const GROUP_CHILD_INDENT = 'tw:pl-8';\n\ntype Props = {\n value: unknown;\n children: ReactNode;\n /** `undefined` for a group that does not collapse — no chevron. */\n expanded?: boolean;\n /** `all` for a Cmd-click (Ctrl elsewhere): fold or unfold every group; `from` is in the list. */\n onToggle: (all: boolean, from: Element) => void;\n /**\n * `'mixed'` for a partial selection; `undefined` for an unselectable row that toggles on press.\n * Drawn here: Base UI would put its indicator ahead of the chevron.\n */\n checked?: boolean | 'mixed';\n /** The children's indicator, mirrored by a `checked` row. */\n indicator?: 'check' | 'checkbox';\n disabled?: boolean;\n /** Every item it would pick is locked: looks disabled, still highlights. */\n locked?: boolean;\n};\n\n/**\n * A group's own row, standing for the whole group.\n *\n * - Keyboard-navigable like any other row.\n * - The chevron toggles by pointer, Cmd- or Ctrl-click toggles every group; its tooltip says so.\n * - `ArrowRight` / `ArrowLeft` are handled by the owning control.\n */\nexport const ComboboxGroupHeader = ({\n value,\n children,\n expanded,\n onToggle,\n checked,\n indicator = 'check',\n disabled,\n locked,\n}: Props) => {\n const toggleFromChevron = (event: MouseEvent) => {\n // Keep the chevron's click from selecting a selectable row.\n event.stopPropagation();\n onToggle(isToggleAllClick(event), event.currentTarget);\n };\n\n return (\n <ComboboxItem\n value={value}\n disabled={disabled}\n locked={locked}\n // An option allows no `aria-expanded`; screen readers read the description after the name.\n aria-description={expanded === undefined ? undefined : expanded ? 'Expanded' : 'Collapsed'}\n {...(checked !== undefined && { 'aria-selected': checked === true })}\n indicator=\"none\"\n className=\"tw:font-medium\"\n onClick={\n checked !== undefined\n ? undefined\n : (event) => {\n event.preventBaseUIHandler();\n onToggle(isToggleAllClick(event), event.currentTarget);\n }\n }\n icon={\n <>\n {expanded !== undefined && (\n <ToggleAllTooltip expanded={expanded}>\n <span\n aria-hidden\n data-slot=\"combobox-group-toggle\"\n // An icon button: its own hover, and it still folds a disabled row.\n className=\"tw:pointer-events-auto tw:-m-1 tw:inline-flex tw:shrink-0 tw:cursor-pointer tw:rounded tw:p-1 tw:transition-colors tw:hover:bg-foreground/10\"\n onClick={toggleFromChevron}\n >\n <ChevronRight\n className={cn('tw:transition-transform', expanded && 'tw:rotate-90')}\n />\n </span>\n </ToggleAllTooltip>\n )}\n {checked !== undefined && <GroupIndicator checked={checked} variant={indicator} />}\n </>\n }\n >\n {children}\n </ComboboxItem>\n );\n};\n\n/**\n * A group row's selection mark: all, some, or none.\n *\n * - Base UI's indicator is binary, so the row draws its own.\n * - `checkbox` matches the children's leading box; `check` their trailing mark.\n */\nconst GroupIndicator = ({\n checked,\n variant,\n}: {\n checked: boolean | 'mixed';\n variant: 'check' | 'checkbox';\n}) => {\n const Mark = checked === 'mixed' ? Minus : Check;\n\n if (variant === 'checkbox') {\n return (\n <span\n aria-hidden\n data-checked={checked}\n className={cn(\n 'tw:inline-flex tw:size-4 tw:shrink-0 tw:items-center tw:justify-center',\n 'tw:rounded tw:border tw:border-input tw:bg-background',\n checked !== false && 'tw:border-primary tw:bg-primary',\n )}\n >\n {checked !== false && (\n <Mark className=\"tw:size-3 tw:stroke-[4px] tw:!text-primary-foreground\" />\n )}\n </span>\n );\n }\n\n if (checked === false) return null;\n\n return (\n <Mark\n aria-hidden\n className={cn(\n 'tw:pointer-events-none tw:absolute tw:right-2 tw:size-4',\n 'tw:group-data-[highlighted]/combobox-item:text-hover-foreground',\n )}\n />\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 // Soft grey 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 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 { Fragment, type ReactNode } from 'react';\n\nimport { ComboboxList } from './ComboboxList';\nimport { ComboboxCollection, ComboboxGroup, ComboboxGroupLabel } from './Group';\nimport type { Group, ListRenderProps } from './types';\nimport { isGroupItem, isLooseItem } from './utils';\n\n/** A Base UI collection child whose rows are keyed by position, as React matches unkeyed ones. */\nconst keyed =\n <Entry,>(render: (entry: Entry) => ReactNode) =>\n (entry: Entry, index: number) =>\n (\n // oxlint-disable-next-line react/no-array-index-key\n <Fragment key={index}>{render(entry)}</Fragment>\n );\n\n/** A combobox list that renders every row; `ComboboxVirtualList` renders only those in view. */\nexport const ComboboxFullList = <Value, GroupShape extends Group<Value> = Group<Value>>({\n renderItem,\n renderGroupItem,\n groupToLabel,\n}: ListRenderProps<Value, GroupShape>) => {\n const renderEntry = (entry: Value | GroupShape) => {\n if (!isGroupItem(entry)) return renderItem(entry);\n\n const [lead] = entry.items;\n if (isLooseItem(lead)) return renderItem(lead);\n\n const label = groupToLabel?.(entry);\n return (\n <ComboboxGroup items={entry.items}>\n {label && <ComboboxGroupLabel>{label}</ComboboxGroupLabel>}\n <ComboboxCollection>{keyed(renderGroupItem)}</ComboboxCollection>\n </ComboboxGroup>\n );\n };\n\n return <ComboboxList>{keyed(renderEntry)}</ComboboxList>;\n};\n","import { Loader2 } from '../../icons';\n\n/**\n * What the empty slot says while the options are loading, in place of the `empty` node.\n *\n * - `Combobox.Empty` is a polite live region, so the switch to this text and back to `empty` once\n * the request settles is announced.\n * - Base UI renders the slot only while the list has nothing to show, so a list that already has\n * items keeps showing them.\n */\nexport const ComboboxLoadingEmpty = () => (\n <span className=\"tw:inline-flex tw:items-center tw:gap-2\">\n <Loader2 className=\"tw:size-4 tw:animate-spin\" />\n Loading…\n </span>\n);\n","import {\n type CSSProperties,\n type ReactNode,\n type Ref,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { Combobox as BaseCombobox } from '@base-ui/react/combobox';\nimport {\n measureElement,\n observeElementRect,\n useVirtualizer,\n type VirtualItem,\n} from '@tanstack/react-virtual';\n\nimport { useElement } from '../../hooks/useElement';\n\nimport { ComboboxList } from './ComboboxList';\nimport { ComboboxGroup, ComboboxGroupLabel } from './Group';\nimport type { Group, ListRenderProps } from './types';\nimport { isGroupItem, isGroupItems, isLooseItem } from './utils';\nimport { type VirtualListHandle, VirtualRowContext } from './virtualList';\n\n/** Rows rendered past each edge of the viewport, so a fast scroll does not paint blank. */\nconst OVERSCAN = 12;\n\ntype ItemRow<Value> = {\n type: 'item';\n item: Value;\n /** Place in Base UI's flat filtered list. */\n index: number;\n setSize: number;\n posInSet: number;\n};\n\ntype Row<Value> = (ItemRow<Value> | { type: 'label' }) & {\n /** The group whose wrapper the row shares; `undefined` for a row outside any group. */\n group?: string;\n /** Spaced from the row above by the gap a fully rendered group puts between its children. */\n padded: boolean;\n};\n\n/** A group's last row is its own kind: a host may space groups apart inside it. */\ntype Kind = 'label' | 'padded' | 'plain' | 'padded-last' | 'plain-last';\nconst isGroupLast = (row: Row<unknown>) =>\n row.type === 'item' && row.group !== undefined && row.posInSet === row.setSize;\nconst kindOf = (row: Row<unknown>): Kind =>\n row.type === 'label'\n ? 'label'\n : `${row.padded ? 'padded' : 'plain'}${isGroupLast(row) ? '-last' : ''}`;\n\n/** A row's React key: its group and its place in it, so a fold leaves other rows mounted. */\nconst placeOf = (row: Row<unknown> | undefined, index: number) => {\n if (!row) return String(index);\n if (row.type === 'label') return `${row.group}:label`;\n return `${row.group ?? 'loose'}:${row.posInSet}`;\n};\n\n/**\n * A row's key for the virtualizer, which keeps measured heights by it.\n *\n * - Folding one group leaves every other row's height in place.\n * - A row that becomes its group's last is estimated afresh, its element kept.\n */\nconst keyOf = (row: Row<unknown> | undefined, index: number) =>\n `${placeOf(row, index)}${row && isGroupLast(row) ? ':last' : ''}`;\n\n/**\n * Base UI's filtered entries as one row per option or group label, in list order.\n *\n * - A group whose lone item is the create row or Select All stays outside any group, as the fully\n * rendered list draws it.\n * - `aria-setsize` counts the options sharing a parent, as a browser does for a rendered list.\n */\nconst toRows = <Value, GroupShape extends Group<Value>>(\n entries: readonly (Value | GroupShape)[],\n groupToLabel: ((group: GroupShape) => ReactNode) | undefined,\n) => {\n const rows: Row<Value>[] = [];\n const rowOfItem: number[] = [];\n const labels = new Map<string, ReactNode>();\n const push = (item: Value, row: Omit<Row<Value> & ItemRow<Value>, 'type' | 'item' | 'index'>) => {\n rows.push({ type: 'item', item, index: rowOfItem.length, ...row });\n rowOfItem.push(rows.length - 1);\n };\n\n if (!isGroupItems<Value, GroupShape>(entries)) {\n const items = entries.filter((entry): entry is Value => !isGroupItem(entry));\n items.forEach((item, i) =>\n push(item, { padded: false, setSize: items.length, posInSet: i + 1 }),\n );\n return { rows, rowOfItem, labels };\n }\n\n const isLoose = (group: GroupShape) => isLooseItem(group.items[0]);\n const looseCount = entries.filter(isLoose).length;\n let loosePosition = 0;\n\n entries.forEach((entry, groupIndex) => {\n if (isLoose(entry)) {\n for (const item of entry.items) {\n push(item, { padded: false, setSize: looseCount, posInSet: ++loosePosition });\n }\n return;\n }\n\n const group = `group-${groupIndex}`;\n const label = groupToLabel?.(entry);\n if (label) {\n labels.set(group, label);\n rows.push({ type: 'label', group, padded: false });\n }\n entry.items.forEach((item, i) =>\n push(item, {\n group,\n padded: Boolean(label) || i > 0,\n setSize: entry.items.length,\n posInSet: i + 1,\n }),\n );\n });\n\n return { rows, rowOfItem, labels };\n};\n\ntype Props<Value, GroupShape extends Group<Value>> = ListRenderProps<Value, GroupShape> & {\n ref?: Ref<VirtualListHandle>;\n};\n\n/**\n * A combobox list that puts only the rows in view into the DOM.\n *\n * - Lists what Base UI filtered, so search and keyboard navigation cover every option.\n * - A group keeps its `role=\"group\"` wrapper, and its name while its label row is out of view.\n * - Rows keep their own height; a row not yet rendered is estimated from those that were.\n */\nexport const ComboboxVirtualList = <Value, GroupShape extends Group<Value> = Group<Value>>({\n renderItem,\n renderGroupItem,\n groupToLabel,\n ref,\n}: Props<Value, GroupShape>) => {\n // State, not a ref: the list mounts with the popup, and its top padding — which the rows start\n // below — is read once it has.\n const [listElement, attachList] = useElement();\n const scrollMargin = useMemo(\n () => (listElement ? Number.parseFloat(getComputedStyle(listElement).paddingTop) || 0 : 0),\n [listElement],\n );\n const filteredItems = BaseCombobox.useFilteredItems<Value | GroupShape>();\n const { rows, rowOfItem, labels } = useMemo(\n () => toRows<Value, GroupShape>(filteredItems, groupToLabel),\n [filteredItems, groupToLabel],\n );\n\n // The smallest height each kind of row has rendered at; 1rem stands in until one has.\n const sizesRef = useRef<Partial<Record<Kind, number>>>({});\n const [rem] = useState(\n () => Number.parseFloat(getComputedStyle(document.documentElement).fontSize) || 0,\n );\n\n const virtualizer = useVirtualizer({\n count: rows.length,\n getItemKey: (index) => keyOf(rows[index], index),\n getScrollElement: () => listElement,\n estimateSize: (index) => {\n const row = rows[index];\n const measured = sizesRef.current;\n const kind = row && kindOf(row);\n const lastKinds = kind?.endsWith('-last')\n ? [measured['plain-last'], measured['padded-last']]\n : [];\n return (\n (kind && measured[kind]) ??\n lastKinds.find((size) => size !== undefined) ??\n measured.plain ??\n measured.padded ??\n rem\n );\n },\n measureElement: (element, entry, instance) => {\n const size = measureElement(element, entry, instance);\n const row = rows[instance.indexFromElement(element)];\n if (row) {\n const kind = kindOf(row);\n sizesRef.current[kind] = Math.min(sizesRef.current[kind] ?? size, size);\n }\n return size;\n },\n // The popup is unbounded until Base UI positions it, and never taller than the window once it\n // is — so the first reading would otherwise mount every row.\n observeElementRect: (instance, callback) =>\n observeElementRect(instance, (rect) =>\n callback({\n ...rect,\n height: Math.min(rect.height, instance.targetWindow?.innerHeight ?? rect.height),\n }),\n ),\n overscan: OVERSCAN,\n scrollMargin,\n });\n\n useImperativeHandle(ref, () => ({\n scrollToItem: (index) => {\n const row = rowOfItem[index];\n if (row !== undefined) virtualizer.scrollToIndex(row, { align: 'auto' });\n },\n }));\n\n // Consecutive rows of one group share its wrapper; a row outside any group stands alone.\n const segments: { group?: string; start: number; items: VirtualItem[] }[] = [];\n for (const virtualItem of virtualizer.getVirtualItems()) {\n const group = rows[virtualItem.index]?.group;\n const last = segments.at(-1);\n if (group !== undefined && last?.group === group) last.items.push(virtualItem);\n else segments.push({ group, start: virtualItem.start, items: [virtualItem] });\n }\n\n const placeAt = (start: number): CSSProperties => ({\n position: 'absolute',\n top: 0,\n left: 0,\n width: '100%',\n transform: `translateY(${start - scrollMargin}px)`,\n });\n\n const renderRow = ({ index, start }: VirtualItem) => {\n const row = rows[index];\n if (!row) return null;\n return (\n <div\n key={placeOf(row, index)}\n data-index={index}\n ref={virtualizer.measureElement}\n className={row.padded ? 'tw:pt-0.5' : undefined}\n style={row.group === undefined ? placeAt(start) : undefined}\n // A group's last row, for a host that spaces groups apart inside the measured rows.\n data-group-last={isGroupLast(row) ? '' : undefined}\n >\n {row.type === 'label' ? (\n <ComboboxGroupLabel>{labels.get(row.group ?? '')}</ComboboxGroupLabel>\n ) : (\n <VirtualRowContext\n value={{\n index: row.index,\n 'aria-setsize': row.setSize,\n 'aria-posinset': row.posInSet,\n }}\n >\n {row.group === undefined ? renderItem(row.item) : renderGroupItem(row.item)}\n </VirtualRowContext>\n )}\n </div>\n );\n };\n\n return (\n <ComboboxList ref={attachList}>\n <div\n style={{ position: 'relative', width: '100%', height: `${virtualizer.getTotalSize()}px` }}\n >\n {segments.flatMap(({ group, start, items }) => {\n if (group === undefined) return items.map(renderRow);\n\n const label = labels.get(group);\n const labelInView = items.some((item) => rows[item.index]?.type === 'label');\n return (\n <ComboboxGroup key={group} className=\"tw:gap-0\" style={placeAt(start)}>\n {label && !labelInView && (\n <ComboboxGroupLabel className=\"tw:sr-only\">{label}</ComboboxGroupLabel>\n )}\n {items.map(renderRow)}\n </ComboboxGroup>\n );\n })}\n </div>\n </ComboboxList>\n );\n};\n","import { type ComponentProps, type ReactNode, type Ref, useCallback } from 'react';\n\nimport { Plus } from '../../icons';\nimport { cn } from '../../utils';\n\nimport { ComboboxGroupHeader, GROUP_CHILD_INDENT } from './Group/ComboboxGroupHeader';\nimport { ComboboxEmpty } from './ComboboxEmpty';\nimport { ComboboxFullList } from './ComboboxFullList';\nimport { ComboboxItem } from './ComboboxItem';\nimport { ComboboxLoadingEmpty } from './ComboboxLoadingEmpty';\nimport { ComboboxVirtualList } from './ComboboxVirtualList';\nimport type { GroupHeaders } from './groupHeaders';\nimport type { Group } from './types';\nimport { isCreatableItem, isEntriesGroup, isSelectAllItem } from './utils';\nimport type { VirtualListHandle } from './virtualList';\n\ntype GroupHeaderProps = ComponentProps<typeof ComboboxGroupHeader>;\n\n/** A group's items fade and slide in as it unfolds and out as it folds; nothing under reduced motion. */\nconst ITEM_MOTION = {\n entering:\n 'tw:motion-safe:animate-in tw:motion-safe:fade-in-0 tw:motion-safe:slide-in-from-top-1 tw:motion-safe:duration-150 tw:motion-safe:ease-out',\n leaving:\n 'tw:motion-safe:animate-out tw:motion-safe:fade-out-0 tw:motion-safe:slide-out-to-top-1 tw:motion-safe:duration-100 tw:motion-safe:ease-in tw:motion-safe:fill-mode-forwards',\n} as const;\n\ntype Props<Value, GroupShape extends Group<Value>> = {\n isLoading: boolean;\n empty: ReactNode;\n /** Windows the list; `listRef` then reaches the windowed list. */\n virtualized: boolean;\n listRef: Ref<VirtualListHandle>;\n groupHeaders: GroupHeaders<Value, GroupShape>;\n groupToLabel: (group: GroupShape) => ReactNode;\n indicator?: GroupHeaderProps['indicator'];\n itemToLabel: (item: Value) => ReactNode;\n itemToIcon: (item: Value) => ReactNode;\n itemToDisabled: (item: Value) => boolean;\n /** A selected item the user can't remove: looks disabled, still highlights. */\n itemToLocked?: (item: Value) => boolean;\n /** The create row's text; receives the row's value. */\n createLabel: (value: string) => ReactNode;\n /** A selectable group row's mark and state; left unset, a group row only folds. */\n groupRowState?: (\n row: Value,\n ) => Required<Pick<GroupHeaderProps, 'checked' | 'disabled'>> & Pick<GroupHeaderProps, 'locked'>;\n};\n\n/**\n * What a combobox popup lists: every row, the empty slot, and the loading text in it.\n *\n * - The list is windowed while `virtualized`, fully rendered otherwise.\n */\nexport const ComboboxOptions = <Value, GroupShape extends Group<Value> = Group<Value>>({\n isLoading,\n empty,\n virtualized,\n listRef,\n groupHeaders,\n groupToLabel,\n indicator,\n itemToLabel,\n itemToIcon,\n itemToDisabled,\n itemToLocked,\n createLabel,\n groupRowState,\n}: Props<Value, GroupShape>) => {\n const renderItem = (item: Value, className?: string) => {\n if (isSelectAllItem(item)) {\n return (\n <ComboboxItem value={item} indicator=\"checkbox\">\n {item.label}\n </ComboboxItem>\n );\n }\n if (isCreatableItem(item)) {\n return (\n <ComboboxItem value={item} icon={<Plus />}>\n {createLabel(item.value)}\n </ComboboxItem>\n );\n }\n\n return (\n <ComboboxItem\n value={item}\n indicator={indicator}\n icon={itemToIcon(item)}\n disabled={itemToDisabled(item)}\n locked={itemToLocked?.(item)}\n className={className}\n >\n {itemToLabel(item)}\n </ComboboxItem>\n );\n };\n\n const renderGroupItem = (item: Value) => {\n const header = groupHeaders.headerOf(item);\n if (!header) {\n const motion = groupHeaders.motionOf(item);\n return renderItem(\n item,\n cn(groupHeaders.collapsible && GROUP_CHILD_INDENT, motion && ITEM_MOTION[motion]),\n );\n }\n\n const state = groupRowState?.(item);\n return (\n <ComboboxGroupHeader\n value={item}\n expanded={groupHeaders.collapsible ? !header.collapsed : undefined}\n onToggle={(all, from) =>\n all\n ? groupHeaders.setAllCollapsed(!header.collapsed, from)\n : groupHeaders.toggle(header.index, from)\n }\n checked={state?.checked}\n indicator={indicator}\n disabled={state?.disabled ?? false}\n locked={state?.locked}\n >\n {groupToLabel(header.group)}\n </ComboboxGroupHeader>\n );\n };\n\n // Skips the group `toEntries` made; stable, since the windowed list memoizes its rows on it.\n const labelOfGroup = useCallback(\n (group: GroupShape) => (isEntriesGroup(group) ? undefined : groupToLabel(group)),\n [groupToLabel],\n );\n\n const listProps = {\n renderItem,\n renderGroupItem,\n groupToLabel: groupHeaders.enabled ? undefined : labelOfGroup,\n };\n\n return (\n <>\n <ComboboxEmpty>{isLoading ? <ComboboxLoadingEmpty /> : empty}</ComboboxEmpty>\n {virtualized ? (\n <ComboboxVirtualList<Value, GroupShape> ref={listRef} {...listProps} />\n ) : (\n <ComboboxFullList<Value, GroupShape> {...listProps} />\n )}\n </>\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 { useMemo } from 'react';\n\nimport { toEntries } from './utils';\n\n/**\n * `list` followed by the values `allowCreate` minted, as entries of it; stable while both are.\n *\n * - Listed so a created value stays pickable: Base UI drops a value missing from `items`.\n */\nexport const useWithCreated = <Entry, Value>(list: readonly Entry[], created: readonly Value[]) =>\n useMemo(\n () => (created.length === 0 ? list : [...list, ...toEntries(list, created)]),\n [list, created],\n );\n","import { useLayoutEffect, useRef } from 'react';\n\n/** How long the groups under a fold take to slide to their new place. */\nconst SLIDE_MS = 150;\n/** A capture no commit moved anything for in this long is dropped. */\nconst STALE_MS = 500;\n\ntype Capture = { list: Element; tops: Map<Element, number>; at: number };\n\nconst listOf = (from: Element) =>\n from.closest('[role=listbox]') ??\n from.ownerDocument.getElementById(from.getAttribute('aria-controls') ?? '');\n\nconst topIn = (list: Element, element: Element) =>\n element.getBoundingClientRect().top - list.getBoundingClientRect().top + list.scrollTop;\n\n/**\n * Slides a list's groups from where they sat before a fold to where it puts them.\n *\n * - `capture` records each group's place; the next commit that moves one plays the slide.\n * - A group the windowed list only now renders slides by the move of the group above it.\n * - The caller skips `capture` under reduced motion; nothing plays without Web Animations.\n */\nexport const useGroupFlip = (enabled: boolean) => {\n const captureRef = useRef<Capture | null>(null);\n const slidesRef = useRef(new WeakMap<Element, { animation: Animation; shift: number }>());\n\n // Where a group sits without the slide it is still playing.\n const settledTop = (list: Element, group: Element) => {\n const slide = slidesRef.current.get(group);\n const progress = slide?.animation.effect?.getComputedTiming().progress;\n const offset = slide && typeof progress === 'number' ? slide.shift * (1 - progress) : 0;\n return topIn(list, group) - offset;\n };\n\n useLayoutEffect(() => {\n const capture = captureRef.current;\n if (!capture) return;\n if (performance.now() - capture.at > STALE_MS) {\n captureRef.current = null;\n return;\n }\n\n const groups = [...capture.list.querySelectorAll('[role=group]')];\n let lastShift = 0;\n const shifts = groups.map((group) => {\n const before = capture.tops.get(group);\n const shift = before === undefined ? lastShift : before - settledTop(capture.list, group);\n lastShift = shift;\n return shift;\n });\n if (shifts.every((shift) => Math.abs(shift) < 0.5)) return;\n\n captureRef.current = null;\n groups.forEach((group, index) => {\n const shift = shifts[index] ?? 0;\n slidesRef.current.get(group)?.animation.cancel();\n if (Math.abs(shift) < 0.5) return;\n const animation = group.animate(\n [{ transform: `translateY(${shift}px)` }, { transform: 'translateY(0)' }],\n { duration: SLIDE_MS, easing: 'ease-out', composite: 'add' },\n );\n slidesRef.current.set(group, { animation, shift });\n });\n });\n\n return {\n /** Records where the groups of the list `from` belongs to sit now. */\n capture: (from: Element | null | undefined) => {\n const list = from && listOf(from);\n if (!enabled || !list || typeof list.animate !== 'function') return;\n const tops = new Map<Element, number>();\n for (const group of list.querySelectorAll('[role=group]')) {\n tops.set(group, topIn(list, group));\n }\n captureRef.current = { list, tops, at: performance.now() };\n },\n };\n};\n","import { type KeyboardEvent, useEffect, useLayoutEffect, useRef, useState } from 'react';\nimport type { BaseUIEvent } from '@base-ui/react/types';\n\nimport { useGroupFlip } from './groupFlip';\nimport type { Group } from './types';\nimport { createGroupHeaderItem, isGroupItems } from './utils';\n\ntype Header<Value, GroupShape extends Group<Value>> = {\n group: GroupShape;\n index: number;\n /** Whether the group hides its items — never while a query is active. */\n collapsed: boolean;\n /** Items matching the query — all of them without a query. */\n matching: readonly Value[];\n};\n\n/** How long a folding group's items fade out before they leave the list. */\nconst FOLD_MS = 100;\n/** How long an unfolding group's items animate in; their marker clears after it. */\nconst ENTER_MS = 150;\n\nconst NO_FOLDS: ReadonlySet<number> = new Set();\n\nconst hasMotion = () =>\n typeof window.matchMedia === 'function' &&\n !window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n\ntype Options<Value, GroupShape extends Group<Value>> = {\n items: readonly (Value | GroupShape)[];\n collapsible: boolean;\n selectable: boolean;\n query: string;\n /** Only called while there is a query. */\n matches: (item: Value) => boolean;\n /** The value a group's row stands for (`Combobox`); unset, the row is a sentinel. */\n groupToValue?: (group: GroupShape) => Value;\n /** Also tells the sentinel rows apart. */\n isItemEqualToValue: (a: Value, b: Value) => boolean;\n /** Read each time the popup opens: a group it accepts starts folded. */\n startsCollapsed?: (group: GroupShape) => boolean;\n /** The popup mounts open, so `startsCollapsed` applies from the first render. */\n startsOpen?: boolean;\n};\n\n/**\n * Gives each group a row (rendered with `ComboboxGroupHeader`) and collapses groups on request.\n *\n * - The row is the group's first item, so Base UI navigates, filters and presses it.\n * - A collapsed group hands Base UI only its row: Base UI never filters an empty query.\n * - A query opens every group with a match; a fold made under it lasts until the query changes.\n * - A row shows only while its group matches.\n * - Collapse state is keyed by a group's position in `items`.\n */\nexport const useGroupHeaders = <Value, GroupShape extends Group<Value>>({\n items,\n collapsible,\n selectable,\n query,\n matches,\n groupToValue,\n isItemEqualToValue,\n startsCollapsed,\n startsOpen = false,\n}: Options<Value, GroupShape>) => {\n const [collapsedIndexes, setCollapsedIndexes] = useState<ReadonlySet<number>>(() =>\n startsOpen && collapsible && startsCollapsed && isGroupItems<Value, GroupShape>(items)\n ? new Set(items.flatMap((group, index) => (startsCollapsed(group) ? [index] : [])))\n : new Set(),\n );\n const [searchFolds, setSearchFolds] = useState<{ query: string; indexes: ReadonlySet<number> }>({\n query: '',\n indexes: new Set(),\n });\n /** The folds that apply now: those made without a query, or under this very query. */\n const folded: ReadonlySet<number> =\n query === '' ? collapsedIndexes : searchFolds.query === query ? searchFolds.indexes : NO_FOLDS;\n // The query on screen, for a fold that lands after it may have changed.\n const queryRef = useRef(query);\n useLayoutEffect(() => {\n queryRef.current = query;\n }, [query]);\n const highlightedRef = useRef<unknown>(undefined);\n /** The groups animating, and the query their fold belongs to. */\n const [motion, setMotion] = useState<{\n indexes: ReadonlySet<number>;\n folding: boolean;\n scope: string;\n } | null>(null);\n const foldTimerRef = useRef<ReturnType<typeof setTimeout>>(undefined);\n useEffect(() => () => clearTimeout(foldTimerRef.current), []);\n const flip = useGroupFlip(collapsible);\n\n const enabled = (collapsible || selectable) && isGroupItems<Value, GroupShape>(items);\n const headers = new Map<unknown, Header<Value, GroupShape>>();\n\n const listItems = !enabled\n ? items\n : items.map((group, index) => {\n const collapsed = collapsible && folded.has(index);\n const matching = query === '' ? group.items : group.items.filter(matches);\n const row = groupToValue ? groupToValue(group) : createGroupHeaderItem(index);\n headers.set(row, { group, index, collapsed, matching });\n\n return { ...group, items: collapsed ? [row] : [row, ...group.items] };\n });\n\n /**\n * Folds or unfolds groups under `scope`, the query the toggle was made under.\n *\n * - A fold made without a query always lands.\n * - A fold made under a query the input no longer holds is dropped: it would never show.\n */\n const setCollapsed = (indexes: Iterable<number>, collapsed: boolean, scope = query) => {\n const apply = (prev: ReadonlySet<number>) => {\n const next = new Set(prev);\n for (const index of indexes) {\n if (collapsed) next.add(index);\n else next.delete(index);\n }\n return next.size === prev.size && [...next].every((index) => prev.has(index)) ? prev : next;\n };\n if (scope === '') setCollapsedIndexes(apply);\n else if (scope === queryRef.current) {\n setSearchFolds((prev) => {\n const base = prev.query === scope ? prev.indexes : NO_FOLDS;\n const next = apply(base);\n return next === base && prev.query === scope ? prev : { query: scope, indexes: next };\n });\n }\n };\n\n const endMotionAfter = (ms: number, then?: () => void) => {\n clearTimeout(foldTimerRef.current);\n foldTimerRef.current = setTimeout(() => {\n then?.();\n setMotion(null);\n }, ms);\n };\n\n const folding: ReadonlySet<number> = motion?.folding ? motion.indexes : new Set();\n /** A group still fading out counts as folded. */\n const isCollapsed = (index: number) => folded.has(index) || folding.has(index);\n\n /**\n * Unfolds groups with their items animating in, or fades them out, then folds them.\n *\n * - The groups under them slide to their new place.\n * - Folds still fading out finish at once, except those this call unfolds again.\n */\n const animate = (indexes: readonly number[], collapse: boolean, from?: Element | null) => {\n clearTimeout(foldTimerRef.current);\n const animated = hasMotion();\n const finishing = [...folding].filter((index) => collapse || !indexes.includes(index));\n const changing = indexes.filter((index) => isCollapsed(index) !== collapse);\n // Only a layout about to change is worth sliding from.\n if (animated && (finishing.length > 0 || changing.length > 0)) flip.capture(from);\n if (motion) setCollapsed(finishing, true, motion.scope);\n if (!animated || changing.length === 0) {\n setCollapsed(changing, collapse);\n setMotion(null);\n return;\n }\n const scope = query;\n setMotion({ indexes: new Set(changing), folding: collapse, scope });\n if (collapse) endMotionAfter(FOLD_MS, () => setCollapsed(changing, true, scope));\n else {\n setCollapsed(changing, false);\n endMotionAfter(ENTER_MS);\n }\n };\n\n /** Unfolds a folded group, folds an open one. */\n const toggle = (index: number, from?: Element | null) =>\n animate([index], !isCollapsed(index), from);\n\n /** Folds or unfolds every group. */\n const setAllCollapsed = (collapse: boolean, from?: Element | null) => {\n if (!isGroupItems<Value, GroupShape>(items)) return;\n animate(\n items.map((_, index) => index),\n collapse,\n from,\n );\n };\n\n const groupIndexOf = new Map<unknown, number>();\n if (motion && enabled && isGroupItems<Value, GroupShape>(items)) {\n for (const index of motion.indexes) {\n for (const item of items[index]?.items ?? []) groupIndexOf.set(item, index);\n }\n }\n\n const headerOf = (item: unknown) => headers.get(item);\n\n // Rows are rebuilt every render, so fall back to equality for the highlighted row.\n const highlightedHeader = () => {\n const item = highlightedRef.current;\n if (item === undefined) return undefined;\n const header = headers.get(item);\n if (header) return header;\n for (const [row, entry] of headers) {\n if (isItemEqualToValue(row as Value, item as Value)) return entry;\n }\n return undefined;\n };\n\n return {\n enabled,\n /** `items` with group rows added and collapsed groups' items removed. */\n items: listItems,\n collapsible,\n headerOf,\n toggle,\n setAllCollapsed,\n /** `entering` / `leaving` for an item of the group that last unfolded / is folding. */\n motionOf: (item: unknown) => {\n if (!motion || !groupIndexOf.has(item)) return undefined;\n return motion.folding ? 'leaving' : 'entering';\n },\n /** `filter` verdict for a group row (matches while its group does); `undefined` otherwise. */\n filterHeader: (item: unknown) => {\n const header = headerOf(item);\n return header ? header.matching.length > 0 : undefined;\n },\n /** For the root's `onItemHighlighted`: which row the keyboard would toggle. */\n onItemHighlighted: (item: unknown) => {\n highlightedRef.current = item;\n },\n /** For the root's `onOpenChange`: clears the highlight on close, folds `startsCollapsed` on open. */\n onOpenChange: (open: boolean) => {\n if (!open) highlightedRef.current = undefined;\n clearTimeout(foldTimerRef.current);\n if (motion?.folding) setCollapsed(motion.indexes, true, motion.scope);\n setMotion(null);\n if (open && collapsible && startsCollapsed && isGroupItems<Value, GroupShape>(items)) {\n setCollapsedIndexes(\n new Set(items.flatMap((group, index) => (startsCollapsed(group) ? [index] : []))),\n );\n }\n },\n /**\n * For the input's `onKeyDown`: `ArrowRight` / `ArrowLeft` expand / collapse the highlighted row.\n * Only without a query; also stops Base UI moving to the chips.\n */\n onInputKeyDown: (event: BaseUIEvent<KeyboardEvent<HTMLInputElement>>) => {\n if (!collapsible || query !== '') return;\n if (event.key !== 'ArrowRight' && event.key !== 'ArrowLeft') return;\n const header = highlightedHeader();\n if (!header) return;\n\n event.preventDefault();\n event.preventBaseUIHandler();\n if (isCollapsed(header.index) === (event.key === 'ArrowRight')) {\n toggle(header.index, event.currentTarget);\n }\n },\n };\n};\n\nexport type GroupHeaders<Value, GroupShape extends Group<Value>> = ReturnType<\n typeof useGroupHeaders<Value, GroupShape>\n>;\n","import { useEffect } from 'react';\n\nimport { useStableCallback } from '../../hooks/useStableCallback';\nimport { noop } from '../../utils';\n\n/**\n * The text a combobox's input takes, with `inputValueSanitizer` applied to what the user typed.\n *\n * - `input-change` is the only reason carrying typed text. Every other one carries text the\n * control itself put there — an item's label, or the empty string a clear leaves — which a\n * sanitizer aimed at typed characters would mangle.\n * - A sanitizer sees the whole text on every keystroke, so it has to rewrite rather than drop:\n * one calling `trim()` swallows the space before the next word.\n */\nexport const sanitizeTypedInput = (\n next: string,\n reason: string,\n sanitizer: ((input: string) => string) | undefined,\n) => (reason === 'input-change' ? (sanitizer?.(next) ?? next) : next);\n\n/**\n * Reports the query the list filters by to the control's owner.\n *\n * - Fires from an effect rather than the input handler because `query` is derived: in `Combobox`\n * a selection showing its own label empties it without a keystroke, so the handler never sees\n * every value it takes.\n * - The mount render reports too, so an owner fetching on the query needs no first fetch of its\n * own.\n */\nexport const useQueryReporter = (query: string, onQueryChange?: (query: string) => void) => {\n const report = useStableCallback(onQueryChange ?? noop);\n\n useEffect(() => {\n report(query);\n }, [query, report]);\n};\n","import { type ComponentProps, type ReactNode, useCallback, useMemo, useState } from 'react';\nimport { Combobox as BaseCombobox } from '@base-ui/react/combobox';\n\nimport { cn } from '../../utils';\nimport { forwardAccessibleName, type WithAccessibleName } from '../../utils/accessibleName';\nimport { InputGroup } from '../InputGroup';\n\nimport { ComboboxChip } from './ComboboxChip';\nimport { ComboboxChips } from './ComboboxChips';\nimport { ComboboxClearButton } from './ComboboxClearButton';\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 { ComboboxOpenButton } from './ComboboxOpenButton';\nimport { ComboboxOptions } from './ComboboxOptions';\nimport { ComboboxRoot } from './ComboboxRoot';\nimport { ComboboxSeparator } from './ComboboxSeparator';\nimport { useWithCreated } from './createdItems';\nimport { ComboboxCollection, ComboboxGroup, ComboboxGroupLabel } from './Group';\nimport { useGroupHeaders } from './groupHeaders';\nimport { useQueryReporter } from './query';\nimport type { Group } from './types';\nimport {\n createCreatableItem,\n defaultGroupToLabel,\n defaultItemToDisabled,\n defaultItemToIcon,\n defaultQueryToCreateLabel,\n defaultRowLabel,\n defaultToCreateValue,\n flatItems,\n isCreatableItem,\n isGroupHeaderItem,\n toEntries,\n toLabel,\n useCreatableStringValue,\n useItemEquality,\n} from './utils';\nimport { useVirtualList, type VirtualizedProps } from './virtualList';\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 = Exclude<NonNullable<ComboboxItemProps['indicator']>, 'none'>;\n\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.\ntype PublicComboboxInputProps = Pick<\n ComboboxInputProps,\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, 'focusVariant' | '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`; `false` hides the create row.\n * - Called only for a non-empty query that matches no existing item.\n */\n canCreate?: (query: string) => boolean;\n};\n\ntype BaseProps<Value, GroupShape extends Group<Value> = Group<Value>> = PublicComboboxInputProps &\n PublicComboboxProps<Value> &\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 /** `false` where clearing must be unreachable, e.g. a required field. */\n allowClear?: boolean;\n empty?: ReactNode;\n /**\n * The options are still arriving — a request for `items` is in flight.\n *\n * - Does not disable the control; pass `disabled` too where the user has to wait.\n */\n isLoading?: boolean;\n indicator?: Indicator;\n prefix?: ReactNode;\n\n /**\n * Rewrites typed text (not the selected label); filter and `allowCreate` see the result.\n * - Rewrite, don't drop: it sees the whole text per keystroke, so `trim()` eats word spaces.\n */\n inputValueSanitizer?: (input: string) => string;\n /**\n * Reports the sanitized query, also on mount; empty while the input shows the selection.\n * - Notification only: the control owns the input text; there is no controlled `inputValue`.\n */\n onQueryChange?: (query: string) => void;\n\n /** Row content, `itemToStringLabel` by default; pass `query` to `MarkedText` to mark a match. */\n itemToLabel?: (item: Value, query: string) => ReactNode;\n itemToIcon?: (item: Value) => ReactNode;\n itemToDisabled?: (item: Value) => boolean;\n /**\n * Selection node drawn over the transparent input while closed; typing dissolves it. Clipped.\n * - Decoration: the input keeps `itemToStringLabel` text for screen readers, unlike `prefix`.\n */\n itemToSelectedLabel?: (item: Value) => ReactNode;\n\n /** Defaults to the group's `label`, as `Select` shows it. */\n groupToLabel?: (group: GroupShape) => ReactNode;\n /**\n * Each group gets a toggle row; with `groupToValue`, only the chevron and ←/→ keys toggle it.\n * - A query shows all matches regardless of collapse and hides groups without one.\n */\n collapsibleGroups?: boolean;\n /**\n * Makes each group's row selectable as the returned value.\n * - `itemToStringLabel`, `itemToSelectedLabel` and `itemToDisabled` then receive it too.\n */\n groupToValue?: (group: GroupShape) => Value;\n };\n\ntype Props<Value, GroupShape extends Group<Value> = Group<Value>> = WithAccessibleName<\n BaseProps<Value, GroupShape>\n>;\n\nconst acceptAll = () => true;\nconst NO_ITEMS: readonly never[] = [];\n\nexport const Combobox = <Value, GroupShape extends Group<Value> = Group<Value>>({\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 focusVariant,\n state,\n placeholder,\n allowClear = true,\n name,\n onBlur,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n className,\n\n empty = 'No items',\n isLoading = false,\n indicator,\n prefix,\n virtualized = false,\n\n inputValueSanitizer,\n onQueryChange,\n\n allowCreate,\n queryToCreateValue,\n queryToCreateLabel = defaultQueryToCreateLabel,\n canCreate,\n\n itemToDisabled = defaultItemToDisabled,\n itemToLabel: itemToLabelProp,\n itemToIcon = defaultItemToIcon,\n itemToSelectedLabel,\n groupToLabel = defaultGroupToLabel,\n collapsibleGroups = false,\n groupToValue,\n ...accessibleName\n}: Props<Value, GroupShape>) => {\n /** An item's string identity: input text, default search subject, accessible value. */\n const labelOf = useCallback(\n (item: Value) => itemToStringLabelProp?.(item) ?? toLabel(item),\n [itemToStringLabelProp],\n );\n const itemToLabel = itemToLabelProp ?? defaultRowLabel(itemToStringLabelProp);\n\n // What the user typed, or `null` while the control shows its selection.\n // - Input text and query both derive from it.\n // - Reset on close here: Base UI's sync-back skips text already equal to the label.\n const [typedText, setTypedText] = useState<string | null>(null);\n\n // The held item, controlled or not; mirrored from Base UI while uncontrolled.\n // - `null` is both \"nothing selected\" and the adder shape's pinned value.\n // - Read here, not via `BaseCombobox.Value`: the query gate and two classNames need it.\n const [uncontrolledValue, setUncontrolledValue] = useState<Value | null>(defaultValue ?? null);\n const selectedItem = value !== undefined ? value : uncontrolledValue;\n\n const selectedLabel = selectedItem == null ? null : labelOf(selectedItem);\n\n // Whether the on-screen text is the selection rather than a query.\n // - Compares with the label, not `null`: a query edited back to the label reads the same.\n const isShowingSelection =\n selectedLabel !== null && (typedText === null || typedText === selectedLabel);\n\n // The query, else the selection's label, which is what a screen reader reports.\n const inputValue = typedText ?? selectedLabel ?? '';\n // Shown only while the input's text is still the selection's label.\n const selectedNode =\n itemToSelectedLabel && selectedItem != null && isShowingSelection\n ? itemToSelectedLabel(selectedItem)\n : null;\n const query = (isShowingSelection ? '' : (typedText ?? '')).trim();\n const queryLower = query.toLowerCase();\n\n useQueryReporter(query, onQueryChange);\n\n // `aria-busy` for the input alone, absent rather than `false` while nothing is loading.\n //\n // - Not on the list: assistive tech may hold back a busy subtree, and the items already listed\n // stay pickable while loading. The empty slot's live region announces \"Loading…\" instead.\n const busy = isLoading || undefined;\n\n const itemsProp = _itemsProp ?? NO_ITEMS;\n const sampleItem = flatItems(itemsProp)[0];\n\n const isItemEqualToValue = useItemEquality(isItemEqualToValueProp);\n\n // The one value `allowCreate` minted, listed while it is the selection and `items` lacks it.\n // - An adder pinned to `null` lists none; `items` is scanned only when it or the value changes.\n const [createdItems, setCreatedItems] = useState<Value[]>([]);\n const [createdItem] = createdItems;\n const itemsHoldCreated = useMemo(\n () =>\n createdItem !== undefined &&\n flatItems(itemsProp).some((listed) => isItemEqualToValue(listed, createdItem)),\n [createdItem, itemsProp, isItemEqualToValue],\n );\n const created =\n createdItem !== undefined &&\n !itemsHoldCreated &&\n selectedItem != null &&\n isItemEqualToValue(createdItem, selectedItem)\n ? createdItems\n : NO_ITEMS;\n\n // Stable while the caller's accessor is: Base UI re-filters on every new identity.\n const itemToStringLabel = useCallback<NonNullable<ComboboxProps<Value>['itemToStringLabel']>>(\n (value) => {\n if (isCreatableItem(value)) return value.value;\n if (isGroupHeaderItem(value)) return value.label;\n return labelOf(value);\n },\n [labelOf],\n );\n\n const { contains } = BaseCombobox.useFilter();\n const itemFilter = filter ?? contains;\n const groupHeaders = useGroupHeaders<Value, GroupShape>({\n items: itemsProp,\n collapsible: collapsibleGroups,\n selectable: groupToValue !== undefined,\n query,\n matches: (item) => itemFilter(item, query, itemToStringLabel),\n groupToValue,\n isItemEqualToValue,\n });\n\n const allItems = useWithCreated(itemsProp, created);\n // What the list shows: `allItems` with each group's own row, once `groupHeaders` adds them.\n const listItems = useWithCreated(groupHeaders.items, created);\n\n const showCreateRow = (() => {\n if (!allowCreate || disabled || !query) return false;\n const exactMatch = flatItems(allItems).some(\n (item) => labelOf(item).toLowerCase() === queryLower,\n );\n return !exactMatch && (!canCreate || canCreate(query));\n })();\n\n const items = useMemo(\n () =>\n showCreateRow\n ? [...listItems, ...toEntries(listItems, [createCreatableItem(query)])]\n : listItems,\n [showCreateRow, listItems, query],\n );\n\n // Behind a selection the whole list stays browsable instead of narrowing to that item.\n // - Base UI's `shouldBypassFiltering` covers only a fresh open, not text edited back to the label.\n // - Creatable and group rows bypass the caller's `filter`; a group row matches while a child does.\n const filterHeader = groupHeaders.enabled ? groupHeaders.filterHeader : undefined;\n const queryFilter = useMemo<ComboboxProps<Value>['filter']>(() => {\n if (filterHeader) {\n return (item, query, itemToString) =>\n filterHeader(item) ?? (isCreatableItem(item) || itemFilter(item, query, itemToString));\n }\n if (!allowCreate || !filter) return filter;\n return (item, query, itemToString) =>\n isCreatableItem(item) || filter(item, query, itemToString);\n }, [filterHeader, allowCreate, filter, itemFilter]);\n const wrappedFilter = isShowingSelection ? acceptAll : queryFilter;\n\n const wrappedItemToStringValue = useCreatableStringValue(itemToStringValue, allowCreate);\n\n // Only user typing becomes `typedText` and passes through `inputValueSanitizer`.\n // - Every other reason (item press, clear, unmount sync-back) means \"show the selection\".\n // - The sync-back is never adopted: for a created item it stringifies the internal sentinel.\n const handleInputValueChange: NonNullable<ComboboxProps<Value>['onInputValueChange']> = (\n next,\n { reason },\n ) => {\n if (reason !== 'input-change') {\n setTypedText(null);\n return;\n }\n\n const typed = inputValueSanitizer?.(next) ?? next;\n // Whitespace-only text is dropped: Base UI won't open on it, so no close would discard it.\n // An empty input clears the selection, so it is adopted.\n setTypedText(typed === '' || typed.trim() !== '' ? typed : null);\n };\n\n // Discard the query as the popup starts closing, not after its transition.\n const handleOpenChange: NonNullable<ComboboxProps<Value>['onOpenChange']> = (open) => {\n if (!open) setTypedText(null);\n groupHeaders.onOpenChange(open);\n };\n\n const handleOnValueChange: ComboboxProps<Value>['onValueChange'] = (next, event) => {\n if (isCreatableItem(next)) {\n const newValue = defaultToCreateValue(next.value, sampleItem, queryToCreateValue) as Value;\n setCreatedItems([newValue]);\n setUncontrolledValue(newValue);\n onValueChange?.(newValue, event);\n return;\n }\n\n setUncontrolledValue(next);\n onValueChange?.(next, event);\n };\n\n // Decided on the real options rather than `items`, whose transient create row would switch\n // windowing on and off as the user types.\n const virtualList = useVirtualList(allItems, virtualized);\n\n const comboboxInput = (\n <ComboboxInput\n {...forwardAccessibleName(accessibleName)}\n name={name}\n onBlur={onBlur}\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 // Text stays for screen readers and the caret; `selectedNode` is drawn over it.\n className={cn(\n selectedNode != null &&\n 'tw:text-transparent tw:caret-foreground tw:selection:bg-transparent',\n )}\n />\n );\n\n return (\n <BaseCombobox.Root<Value, false>\n items={items}\n // Otherwise Enter after typing drops the query; this commits the first match or create row.\n autoHighlight\n value={value}\n defaultValue={defaultValue}\n filter={wrappedFilter}\n onValueChange={handleOnValueChange}\n itemToStringLabel={itemToStringLabel}\n isItemEqualToValue={isItemEqualToValue}\n itemToStringValue={wrappedItemToStringValue}\n onOpenChange={handleOpenChange}\n onOpenChangeComplete={onOpenChangeComplete}\n disabled={disabled}\n inputRef={inputRef}\n inputValue={inputValue}\n onInputValueChange={handleInputValueChange}\n virtualized={virtualList.enabled}\n onItemHighlighted={(item, details) => {\n groupHeaders.onItemHighlighted(item);\n virtualList.onItemHighlighted(details);\n }}\n >\n <ComboboxInputGroup state={state} focusVariant={focusVariant} className={className}>\n {itemToSelectedLabel != null ? (\n // The addon overlays the input inside a `relative` wrapper; its `pl-4` and the input's\n // `px-4` share one origin.\n // - Branch on the prop, not `selectedNode`: swapping trees mid-typing drops input focus.\n <div className=\"tw:relative tw:flex tw:min-w-0 tw:flex-1\">\n {(prefix != null || selectedNode != null) && (\n <InputGroup.Addon\n align=\"inline-start\"\n className={cn(\n selectedNode != null &&\n 'tw:pointer-events-none tw:absolute tw:inset-y-0 tw:left-0 tw:max-w-full tw:overflow-hidden',\n )}\n >\n {prefix}\n {selectedNode}\n </InputGroup.Addon>\n )}\n {comboboxInput}\n </div>\n ) : (\n <>\n {prefix != null && <InputGroup.Addon align=\"inline-start\">{prefix}</InputGroup.Addon>}\n {comboboxInput}\n </>\n )}\n <InputGroup.Addon align=\"inline-end\">\n {allowClear && <ComboboxClearButton disabled={disabled} />}\n <ComboboxOpenButton disabled={disabled} isLoading={isLoading} />\n </InputGroup.Addon>\n </ComboboxInputGroup>\n <ComboboxContent>\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 createLabel={queryToCreateLabel}\n groupRowState={\n groupToValue\n ? (row) => ({\n checked: selectedItem != null && isItemEqualToValue(row, selectedItem),\n disabled: itemToDisabled(row),\n })\n : undefined\n }\n />\n </ComboboxContent>\n </BaseCombobox.Root>\n );\n};\n\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\nCombobox.Group = ComboboxGroup;\nCombobox.GroupLabel = ComboboxGroupLabel;\nCombobox.GroupList = ComboboxCollection;\n\nCombobox.Chips = ComboboxChips;\nCombobox.Chip = ComboboxChip;\n","import { toLabel } from './utils';\n\n/** A single searchable text. `null` / `undefined` / `''` stand for \"this item has no such field\". */\ntype Text = string | number | null | undefined;\n\n// Lowercased words of a query.\n//\n// - Splits on whitespace runs, so no empty word matches every text.\n// - Plain `toLowerCase`: `foldCase` only matters for offsets, and none are reported here.\nconst toWords = (query: string) => query.toLowerCase().split(/\\s+/).filter(Boolean);\n\nconst isFilled = (text: Text): text is string | number =>\n text !== null && text !== undefined && text !== '';\n\nconst isTextList = (texts: Text | readonly Text[]): texts is readonly Text[] =>\n Array.isArray(texts);\n\n/**\n * Whether every word of `query` occurs in some of `texts`, ignoring case.\n *\n * - Words match by containment, across texts, in any order; an empty query matches everything.\n * - Plain lowercased `includes`, not `Intl.Collator`: `Muller` does not find `Müller`.\n * - Not interchangeable with kbc-ui's own `matchByWords` (single-space split, keeps empty texts).\n * - A `filter` for when the searchable text is not the label; else use {@link filterByWords}.\n */\nexport const matchByWords = (texts: Text | readonly Text[], query: string) => {\n const words = toWords(query);\n if (words.length === 0) return true;\n\n const haystacks = (isTextList(texts) ? texts : [texts])\n .filter(isFilled)\n .map((text) => String(text).toLowerCase());\n\n return words.every((word) => haystacks.some((haystack) => haystack.includes(word)));\n};\n\n/**\n * `filter` matching the item's displayed label word by word: `filter={filterByWords}`.\n *\n * - Generic, so it keeps the combobox's item type inference.\n * - Label: `itemToStringLabel` if passed, else the item's `label`, `value`, or string form.\n * - Only the label is searched, by design: never match what the user cannot see.\n * - Close over {@link matchByWords} to search other fields.\n */\nexport const filterByWords = <Item>(\n item: Item,\n query: string,\n itemToString?: (item: Item) => string,\n) => matchByWords(itemToString?.(item) ?? toLabel(item), query);\n"],"mappings":"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"}