@keboola/design 17.0.0 → 17.2.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 (191) hide show
  1. package/CHANGELOG.md +48 -1
  2. package/dist/{AIKit-CxKkvN0q.js → AIKit-DiF0LtVr.js} +22 -14
  3. package/dist/AIKit-DiF0LtVr.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-CakN_1cF.js} +6 -6
  31. package/dist/Combobox-CakN_1cF.js.map +1 -0
  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/{PageHeader-DosMyar2.js → PageHeader-CfFKjCzo.js} +2 -2
  67. package/dist/PageHeader-CfFKjCzo.js.map +1 -0
  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 +3 -3
  104. package/dist/flint.js.map +1 -1
  105. package/dist/index.d.ts +410 -354
  106. package/dist/index.js +52 -50
  107. package/dist/internal/blocks/AIKit.js +1 -1
  108. package/dist/internal/blocks/AppShell.js +1 -1
  109. package/dist/internal/blocks/AuthLayout.js +1 -1
  110. package/dist/internal/blocks/BrandEditor.js +1 -1
  111. package/dist/internal/blocks/BulkActionsBar.js +55 -0
  112. package/dist/internal/blocks/BulkActionsBar.js.map +1 -0
  113. package/dist/internal/blocks/ChipEditor.js +2 -2
  114. package/dist/internal/blocks/ClipboardButton.js +1 -1
  115. package/dist/internal/blocks/ColorInput.js +1 -1
  116. package/dist/internal/blocks/ColorModeSwitch.js +1 -1
  117. package/dist/internal/blocks/Command.js +1 -1
  118. package/dist/internal/blocks/CopyField.js +1 -1
  119. package/dist/internal/blocks/DateInput.js +1 -1
  120. package/dist/internal/blocks/DateRangeInput.js +1 -1
  121. package/dist/internal/blocks/ExportMenu.js +2 -2
  122. package/dist/internal/blocks/Form/connectors/ComboboxField.js +2 -2
  123. package/dist/internal/blocks/Form/connectors/MultiComboboxField.js +1 -1
  124. package/dist/internal/blocks/Form.js +2 -2
  125. package/dist/internal/blocks/FormGroup.js +1 -1
  126. package/dist/internal/blocks/InlineEdit.js +1 -1
  127. package/dist/internal/blocks/MultiActionButtonGroup.js +1 -1
  128. package/dist/internal/blocks/MultiCombobox.js +3 -3
  129. package/dist/internal/blocks/NumberInput.js +1 -1
  130. package/dist/internal/blocks/PageHeader.js +1 -1
  131. package/dist/internal/blocks/PageSection.js +31 -0
  132. package/dist/internal/blocks/PageSection.js.map +1 -0
  133. package/dist/internal/blocks/PageToolbar.js +1 -1
  134. package/dist/internal/blocks/PasswordInput.js +2 -2
  135. package/dist/internal/blocks/SearchInput.js +1 -1
  136. package/dist/internal/blocks/SearchInputWithNavigation.js +3 -3
  137. package/dist/internal/blocks/SectionNav.js +1 -1
  138. package/dist/internal/blocks/SplitButton.js +1 -1
  139. package/dist/internal/blocks/TextInput.js +1 -1
  140. package/dist/internal/blocks/Textarea.js +1 -1
  141. package/dist/internal/blocks/TimeInput.js +2 -2
  142. package/dist/internal/components/Alert.js +1 -1
  143. package/dist/internal/components/AlertModal.js +1 -1
  144. package/dist/internal/components/Avatar.js +3 -2
  145. package/dist/internal/components/Avatar.js.map +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 +74 -54
  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 +11 -1
  185. package/dist/AIKit-CxKkvN0q.js.map +0 -1
  186. package/dist/Clipboard-fAkDdpEu.js.map +0 -1
  187. package/dist/ClipboardButton-71Ugbl8c.js.map +0 -1
  188. package/dist/Combobox-DYjvYgl3.js.map +0 -1
  189. package/dist/PageHeader-DosMyar2.js.map +0 -1
  190. package/dist/SectionNav-L81iJBo3.js.map +0 -1
  191. package/dist/Table-BwgBm3hJ.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Combobox-CakN_1cF.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) && '__marker' in entry && 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: Group): ReactNode => {\n const label = 'label' in group ? group.label : undefined;\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,7 +1,7 @@
1
1
  import { cn } from "./classNames-DkX30VJU.js";
2
2
  import { Check, Circle } from "./icons-DDR9dFSr.js";
3
3
  import { ScrollArea } from "./internal/components/ScrollArea.js";
4
- import { TextInput } from "./TextInput--1CfZybC.js";
4
+ import { TextInput } from "./TextInput-BAL-zOAN.js";
5
5
  import { createContext, use } from "react";
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
7
7
  import { Command, CommandInput, defaultFilter, useCommandState } from "cmdk";
@@ -107,4 +107,4 @@ Command$1.Input = CommandInput$1;
107
107
  Command$1.Item = CommandItem;
108
108
  export { Command$1 as Command, CommandGroup, CommandInput$1 as CommandInput, CommandItem, CommandList, defaultFilter, useCommandState };
109
109
 
110
- //# sourceMappingURL=Command-BcTb6GsR.js.map
110
+ //# sourceMappingURL=Command-D6XYzzJf.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Command-BcTb6GsR.js","names":["CommandPrimitive","CommandPrimitive","CommandInput","CmdInput","CommandPrimitive","CommandPrimitive","CommandPrimitive","Command","CommandPrimitive","CommandInput"],"sources":["../src/blocks/Command/CommandContext.tsx","../src/blocks/Command/CommandContent.tsx","../src/blocks/Command/CommandEmpty.tsx","../src/blocks/Command/CommandGroup.tsx","../src/blocks/Command/CommandInput.tsx","../src/blocks/Command/CommandItem/CheckIndicator.tsx","../src/blocks/Command/CommandItem/CommandItem.tsx","../src/blocks/Command/CommandList.tsx","../src/blocks/Command/CommandSeparator.tsx","../src/blocks/Command/Command.tsx"],"sourcesContent":["import { createContext, use } from 'react';\n\n/** Whether the enclosing `Command` is `compact`. */\nexport const CommandContext = createContext(false);\n\nexport const useCommandCompact = () => use(CommandContext);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\nimport { useCommandCompact } from './CommandContext';\n\ntype Props = ComponentProps<'div'>;\n\nexport const CommandContent = ({ className, ...rest }: Props) => {\n const compact = useCommandCompact();\n\n return (\n <div\n {...rest}\n className={cn('tw:flex', 'tw:flex-col', compact ? 'tw:p-2' : 'tw:p-4', 'tw:gap-2', className)}\n />\n );\n};\n","import type { ComponentProps } from 'react';\nimport { Command as CommandPrimitive } from 'cmdk';\n\ntype Props = ComponentProps<typeof CommandPrimitive.Empty>;\n\nexport const CommandEmpty = ({ ...props }: Props) => <CommandPrimitive.Empty {...props} />;\n","import type { ComponentProps } from 'react';\nimport { Command as CommandPrimitive } from 'cmdk';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<typeof CommandPrimitive.Group>;\n\nexport const CommandGroup = ({ className, ...props }: Props) => (\n <CommandPrimitive.Group\n className={cn(\n 'tw:[&_[cmdk-group-heading]]:font-semibold',\n 'tw:[&_[cmdk-group-heading]]:font-sans',\n 'tw:[&_[cmdk-group-heading]]:px-4',\n 'tw:[&_[cmdk-group-heading]]:py-0.5',\n 'tw:[&_[cmdk-group-heading]]:uppercase',\n 'tw:[&_[cmdk-group-heading]]:text-[11px]',\n 'tw:[&_[cmdk-group-heading]]:text-muted-foreground',\n 'tw:[&_[cmdk-group-heading]]:tracking-[1px]',\n 'tw:[&_[cmdk-group-heading]]:border-b',\n 'tw:[&_[cmdk-group-heading]]:border-border',\n 'tw:[&_[cmdk-group-heading]]:my-2',\n className,\n )}\n {...props}\n />\n);\n","import type { ComponentProps } from 'react';\nimport { CommandInput as CmdInput } from 'cmdk';\n\nimport { cn } from '../../utils';\nimport { TextInput } from '../TextInput';\n\nimport { useCommandCompact } from './CommandContext';\n\ntype Props = ComponentProps<typeof TextInput>;\n\n/** The search field; a bare full-width row unless the `Command` is `compact`. */\nexport const CommandInput = ({ ref, className, ...props }: Props) => {\n const compact = useCommandCompact();\n\n return (\n <CmdInput ref={ref} asChild>\n <TextInput\n {...props}\n className={cn(\n !compact &&\n 'tw:!bg-transparent tw:!border-transparent tw:!rounded-none tw:max-h-12 tw:h-12',\n className,\n )}\n />\n </CmdInput>\n );\n};\n","import { Check, Circle } from '../../../icons';\nimport { cn } from '../../../utils';\n\ntype Props = {\n variant?: 'checkbox' | 'radio' | 'default';\n};\n\nexport const CheckIndicator = ({ variant = 'default' }: Props) => {\n if (variant === 'default') return null;\n\n return (\n <span\n data-variant={variant}\n className={cn(\n 'tw:group/check-indicator',\n // positioning\n 'tw:pointer-events-none',\n\n // sizing\n 'tw:size-4',\n 'tw:flex',\n 'tw:items-center',\n 'tw:justify-center',\n\n // border\n 'tw:border',\n 'tw:border-solid',\n 'tw:rounded',\n 'tw:border-input',\n\n 'tw:data-[variant=radio]:rounded-full',\n\n 'tw:data-[variant=checkbox]:rounded',\n 'tw:data-[variant=checkbox]:group-data-[checked=true]/command-item:border-primary',\n 'tw:data-[variant=checkbox]:group-data-[checked=true]/command-item:bg-primary',\n 'tw:shrink-0',\n )}\n >\n {variant === 'checkbox' ? (\n <Check\n className={cn(\n 'tw:hidden',\n // Lucide SVGs default to 24×24; constrain to the 16px indicator slot.\n 'tw:size-3',\n 'tw:stroke-[4px]',\n 'tw:group-data-[checked=true]/command-item:block',\n 'tw:group-data-[variant=checkbox]/check-indicator:text-primary-foreground',\n )}\n />\n ) : (\n <Circle\n className={cn(\n 'tw:hidden',\n // Lucide Circle is stroke-only — force fill to match the stroke so\n // the indicator reads as a solid dot.\n 'tw:size-3',\n 'tw:fill-current',\n 'tw:group-data-[checked=true]/command-item:block',\n 'tw:group-data-[variant=radio]/check-indicator:text-primary',\n )}\n />\n )}\n </span>\n );\n};\n","import type { ComponentProps, ReactNode } from 'react';\nimport { Command as CommandPrimitive } from 'cmdk';\n\nimport { Check } from '../../../icons';\nimport { cn } from '../../../utils';\n\nimport { CheckIndicator } from './CheckIndicator';\n\ntype Props = ComponentProps<typeof CommandPrimitive.Item> & {\n icon?: ReactNode;\n checked?: boolean;\n variant?: ComponentProps<typeof CheckIndicator>['variant'];\n actions?: ReactNode;\n};\n\nexport const CommandItem = ({\n className,\n icon,\n children,\n checked = false,\n variant = 'default',\n actions,\n ...props\n}: Props) => (\n <div className=\"tw:group tw:flex tw:items-center tw:justify-center\">\n <CommandPrimitive.Item\n {...props}\n data-checked={checked}\n data-variant={variant}\n className={cn(\n 'tw:group/command-item',\n 'tw:peer/command-item',\n\n // positioning\n 'tw:relative',\n 'tw:flex',\n 'tw:items-center',\n 'tw:gap-2',\n 'tw:flex-1',\n 'tw:p-2',\n\n // typography\n 'tw:font-sans',\n 'tw:text-sm',\n 'tw:leading-6',\n 'tw:cursor-pointer',\n 'tw:select-none',\n 'tw:outline-hidden',\n\n // The keyboard highlight is the only fill; a checked row shows its indicator or check instead.\n // No colour transition: a fading row would read as a second highlight on ↑/↓.\n 'tw:rounded-md',\n 'tw:data-[selected=true]:bg-hover',\n\n // disabled\n 'tw:aria-disabled:opacity-disabled',\n\n 'tw:aria-disabled:cursor-not-allowed',\n 'tw:aria-disabled:hover:bg-transparent',\n\n // reset styles for checked and disabled\n 'tw:data-[checked=true]:aria-disabled:opacity-100',\n 'tw:data-[checked=true]:aria-disabled:cursor-default',\n className,\n )}\n >\n <CheckIndicator variant={variant} />\n {icon && (\n <span className=\"tw:inline-flex tw:size-4 tw:shrink-0 tw:items-center tw:justify-center tw:text-muted-foreground tw:[&_svg:not([class*='tw:size-'])]:size-4\">\n {icon}\n </span>\n )}\n {children}\n {checked && variant === 'default' && (\n <Check aria-hidden className=\"tw:ml-auto tw:size-4 tw:shrink-0 tw:text-primary\" />\n )}\n </CommandPrimitive.Item>\n\n {actions && (\n <span\n data-slot=\"command-item-actions\"\n className={cn(\n 'tw:hidden',\n 'tw:mx-2',\n 'tw:group-hover:flex',\n 'tw:peer-hover/command-item:flex',\n 'tw:peer-data-[selected=true]/command-item:flex',\n )}\n >\n {actions}\n </span>\n )}\n </div>\n);\n","import type { ComponentProps } from 'react';\nimport { Command as CommandPrimitive } from 'cmdk';\n\nimport { ScrollArea } from '../../components/ScrollArea';\nimport { cn } from '../../utils';\n\nimport { useCommandCompact } from './CommandContext';\n\ntype Props = ComponentProps<typeof CommandPrimitive.List> &\n Pick<ComponentProps<typeof ScrollArea>, 'viewPortClassName'>;\n\nexport const CommandList = ({ ref, className, children, viewPortClassName, ...props }: Props) => {\n const compact = useCommandCompact();\n\n return (\n <ScrollArea\n ref={ref}\n className={cn(!compact && 'tw:px-4 tw:pb-4', className)}\n viewPortClassName={cn(\n 'tw:[&_[cmdk-list-sizer]]:flex',\n 'tw:[&_[cmdk-list-sizer]]:flex-col',\n viewPortClassName,\n )}\n >\n <CommandPrimitive.List {...props}>{children}</CommandPrimitive.List>\n </ScrollArea>\n );\n};\n","import type { ComponentProps } from 'react';\nimport { Command as CommandPrimitive } from 'cmdk';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<typeof CommandPrimitive.Separator>;\n\nexport const CommandSeparator = ({ className, ...props }: Props) => (\n <CommandPrimitive.Separator\n className={cn('tw:h-px', 'tw:bg-border', 'tw:my-2', className)}\n {...props}\n />\n);\n","import type { ComponentProps } from 'react';\nimport { Command as CommandPrimitive } from 'cmdk';\n\nimport { cn } from '../../utils';\n\nimport { CommandContent } from './CommandContent';\nimport { CommandContext } from './CommandContext';\nimport { CommandEmpty } from './CommandEmpty';\nimport { CommandGroup } from './CommandGroup';\nimport { CommandInput } from './CommandInput';\nimport { CommandItem } from './CommandItem';\nimport { CommandList } from './CommandList';\nimport { CommandSeparator } from './CommandSeparator';\n\ntype Props = ComponentProps<typeof CommandPrimitive> & {\n /** Drops the palette padding and the bare search row; suits small surfaces like popovers. */\n compact?: boolean;\n};\n\nexport const Command = ({ className, compact = false, ...rest }: Props) => (\n <CommandContext value={compact}>\n <CommandPrimitive\n className={cn('tw:group/command', 'tailwindcss-preflight', className)}\n {...rest}\n />\n </CommandContext>\n);\n\nCommand.Content = CommandContent;\n\nCommand.Separator = CommandSeparator;\nCommand.List = CommandList;\nCommand.Group = CommandGroup;\nCommand.Empty = CommandEmpty;\nCommand.Input = CommandInput;\n\n// items\nCommand.Item = CommandItem;\n"],"mappings":"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"}
1
+ {"version":3,"file":"Command-D6XYzzJf.js","names":["CommandPrimitive","CommandPrimitive","CommandInput","CmdInput","CommandPrimitive","CommandPrimitive","CommandPrimitive","Command","CommandPrimitive","CommandInput"],"sources":["../src/blocks/Command/CommandContext.tsx","../src/blocks/Command/CommandContent.tsx","../src/blocks/Command/CommandEmpty.tsx","../src/blocks/Command/CommandGroup.tsx","../src/blocks/Command/CommandInput.tsx","../src/blocks/Command/CommandItem/CheckIndicator.tsx","../src/blocks/Command/CommandItem/CommandItem.tsx","../src/blocks/Command/CommandList.tsx","../src/blocks/Command/CommandSeparator.tsx","../src/blocks/Command/Command.tsx"],"sourcesContent":["import { createContext, use } from 'react';\n\n/** Whether the enclosing `Command` is `compact`. */\nexport const CommandContext = createContext(false);\n\nexport const useCommandCompact = () => use(CommandContext);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\nimport { useCommandCompact } from './CommandContext';\n\ntype Props = ComponentProps<'div'>;\n\nexport const CommandContent = ({ className, ...rest }: Props) => {\n const compact = useCommandCompact();\n\n return (\n <div\n {...rest}\n className={cn('tw:flex', 'tw:flex-col', compact ? 'tw:p-2' : 'tw:p-4', 'tw:gap-2', className)}\n />\n );\n};\n","import type { ComponentProps } from 'react';\nimport { Command as CommandPrimitive } from 'cmdk';\n\ntype Props = ComponentProps<typeof CommandPrimitive.Empty>;\n\nexport const CommandEmpty = ({ ...props }: Props) => <CommandPrimitive.Empty {...props} />;\n","import type { ComponentProps } from 'react';\nimport { Command as CommandPrimitive } from 'cmdk';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<typeof CommandPrimitive.Group>;\n\nexport const CommandGroup = ({ className, ...props }: Props) => (\n <CommandPrimitive.Group\n className={cn(\n 'tw:[&_[cmdk-group-heading]]:font-semibold',\n 'tw:[&_[cmdk-group-heading]]:font-sans',\n 'tw:[&_[cmdk-group-heading]]:px-4',\n 'tw:[&_[cmdk-group-heading]]:py-0.5',\n 'tw:[&_[cmdk-group-heading]]:uppercase',\n 'tw:[&_[cmdk-group-heading]]:text-[11px]',\n 'tw:[&_[cmdk-group-heading]]:text-muted-foreground',\n 'tw:[&_[cmdk-group-heading]]:tracking-[1px]',\n 'tw:[&_[cmdk-group-heading]]:border-b',\n 'tw:[&_[cmdk-group-heading]]:border-border',\n 'tw:[&_[cmdk-group-heading]]:my-2',\n className,\n )}\n {...props}\n />\n);\n","import type { ComponentProps } from 'react';\nimport { CommandInput as CmdInput } from 'cmdk';\n\nimport { cn } from '../../utils';\nimport { TextInput } from '../TextInput';\n\nimport { useCommandCompact } from './CommandContext';\n\ntype Props = ComponentProps<typeof TextInput>;\n\n/** The search field; a bare full-width row unless the `Command` is `compact`. */\nexport const CommandInput = ({ ref, className, ...props }: Props) => {\n const compact = useCommandCompact();\n\n return (\n <CmdInput ref={ref} asChild>\n <TextInput\n {...props}\n className={cn(\n !compact &&\n 'tw:!bg-transparent tw:!border-transparent tw:!rounded-none tw:max-h-12 tw:h-12',\n className,\n )}\n />\n </CmdInput>\n );\n};\n","import { Check, Circle } from '../../../icons';\nimport { cn } from '../../../utils';\n\ntype Props = {\n variant?: 'checkbox' | 'radio' | 'default';\n};\n\nexport const CheckIndicator = ({ variant = 'default' }: Props) => {\n if (variant === 'default') return null;\n\n return (\n <span\n data-variant={variant}\n className={cn(\n 'tw:group/check-indicator',\n // positioning\n 'tw:pointer-events-none',\n\n // sizing\n 'tw:size-4',\n 'tw:flex',\n 'tw:items-center',\n 'tw:justify-center',\n\n // border\n 'tw:border',\n 'tw:border-solid',\n 'tw:rounded',\n 'tw:border-input',\n\n 'tw:data-[variant=radio]:rounded-full',\n\n 'tw:data-[variant=checkbox]:rounded',\n 'tw:data-[variant=checkbox]:group-data-[checked=true]/command-item:border-primary',\n 'tw:data-[variant=checkbox]:group-data-[checked=true]/command-item:bg-primary',\n 'tw:shrink-0',\n )}\n >\n {variant === 'checkbox' ? (\n <Check\n className={cn(\n 'tw:hidden',\n // Lucide SVGs default to 24×24; constrain to the 16px indicator slot.\n 'tw:size-3',\n 'tw:stroke-[4px]',\n 'tw:group-data-[checked=true]/command-item:block',\n 'tw:group-data-[variant=checkbox]/check-indicator:text-primary-foreground',\n )}\n />\n ) : (\n <Circle\n className={cn(\n 'tw:hidden',\n // Lucide Circle is stroke-only — force fill to match the stroke so\n // the indicator reads as a solid dot.\n 'tw:size-3',\n 'tw:fill-current',\n 'tw:group-data-[checked=true]/command-item:block',\n 'tw:group-data-[variant=radio]/check-indicator:text-primary',\n )}\n />\n )}\n </span>\n );\n};\n","import type { ComponentProps, ReactNode } from 'react';\nimport { Command as CommandPrimitive } from 'cmdk';\n\nimport { Check } from '../../../icons';\nimport { cn } from '../../../utils';\n\nimport { CheckIndicator } from './CheckIndicator';\n\ntype Props = ComponentProps<typeof CommandPrimitive.Item> & {\n icon?: ReactNode;\n checked?: boolean;\n variant?: ComponentProps<typeof CheckIndicator>['variant'];\n actions?: ReactNode;\n};\n\nexport const CommandItem = ({\n className,\n icon,\n children,\n checked = false,\n variant = 'default',\n actions,\n ...props\n}: Props) => (\n <div className=\"tw:group tw:flex tw:items-center tw:justify-center\">\n <CommandPrimitive.Item\n {...props}\n data-checked={checked}\n data-variant={variant}\n className={cn(\n 'tw:group/command-item',\n 'tw:peer/command-item',\n\n // positioning\n 'tw:relative',\n 'tw:flex',\n 'tw:items-center',\n 'tw:gap-2',\n 'tw:flex-1',\n 'tw:p-2',\n\n // typography\n 'tw:font-sans',\n 'tw:text-sm',\n 'tw:leading-6',\n 'tw:cursor-pointer',\n 'tw:select-none',\n 'tw:outline-hidden',\n\n // The keyboard highlight is the only fill; a checked row shows its indicator or check instead.\n // No colour transition: a fading row would read as a second highlight on ↑/↓.\n 'tw:rounded-md',\n 'tw:data-[selected=true]:bg-hover',\n\n // disabled\n 'tw:aria-disabled:opacity-disabled',\n\n 'tw:aria-disabled:cursor-not-allowed',\n 'tw:aria-disabled:hover:bg-transparent',\n\n // reset styles for checked and disabled\n 'tw:data-[checked=true]:aria-disabled:opacity-100',\n 'tw:data-[checked=true]:aria-disabled:cursor-default',\n className,\n )}\n >\n <CheckIndicator variant={variant} />\n {icon && (\n <span className=\"tw:inline-flex tw:size-4 tw:shrink-0 tw:items-center tw:justify-center tw:text-muted-foreground tw:[&_svg:not([class*='tw:size-'])]:size-4\">\n {icon}\n </span>\n )}\n {children}\n {checked && variant === 'default' && (\n <Check aria-hidden className=\"tw:ml-auto tw:size-4 tw:shrink-0 tw:text-primary\" />\n )}\n </CommandPrimitive.Item>\n\n {actions && (\n <span\n data-slot=\"command-item-actions\"\n className={cn(\n 'tw:hidden',\n 'tw:mx-2',\n 'tw:group-hover:flex',\n 'tw:peer-hover/command-item:flex',\n 'tw:peer-data-[selected=true]/command-item:flex',\n )}\n >\n {actions}\n </span>\n )}\n </div>\n);\n","import type { ComponentProps } from 'react';\nimport { Command as CommandPrimitive } from 'cmdk';\n\nimport { ScrollArea } from '../../components/ScrollArea';\nimport { cn } from '../../utils';\n\nimport { useCommandCompact } from './CommandContext';\n\ntype Props = ComponentProps<typeof CommandPrimitive.List> &\n Pick<ComponentProps<typeof ScrollArea>, 'viewPortClassName'>;\n\nexport const CommandList = ({ ref, className, children, viewPortClassName, ...props }: Props) => {\n const compact = useCommandCompact();\n\n return (\n <ScrollArea\n ref={ref}\n className={cn(!compact && 'tw:px-4 tw:pb-4', className)}\n viewPortClassName={cn(\n 'tw:[&_[cmdk-list-sizer]]:flex',\n 'tw:[&_[cmdk-list-sizer]]:flex-col',\n viewPortClassName,\n )}\n >\n <CommandPrimitive.List {...props}>{children}</CommandPrimitive.List>\n </ScrollArea>\n );\n};\n","import type { ComponentProps } from 'react';\nimport { Command as CommandPrimitive } from 'cmdk';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<typeof CommandPrimitive.Separator>;\n\nexport const CommandSeparator = ({ className, ...props }: Props) => (\n <CommandPrimitive.Separator\n className={cn('tw:h-px', 'tw:bg-border', 'tw:my-2', className)}\n {...props}\n />\n);\n","import type { ComponentProps } from 'react';\nimport { Command as CommandPrimitive } from 'cmdk';\n\nimport { cn } from '../../utils';\n\nimport { CommandContent } from './CommandContent';\nimport { CommandContext } from './CommandContext';\nimport { CommandEmpty } from './CommandEmpty';\nimport { CommandGroup } from './CommandGroup';\nimport { CommandInput } from './CommandInput';\nimport { CommandItem } from './CommandItem';\nimport { CommandList } from './CommandList';\nimport { CommandSeparator } from './CommandSeparator';\n\ntype Props = ComponentProps<typeof CommandPrimitive> & {\n /** Drops the palette padding and the bare search row; suits small surfaces like popovers. */\n compact?: boolean;\n};\n\nexport const Command = ({ className, compact = false, ...rest }: Props) => (\n <CommandContext value={compact}>\n <CommandPrimitive\n className={cn('tw:group/command', 'tailwindcss-preflight', className)}\n {...rest}\n />\n </CommandContext>\n);\n\nCommand.Content = CommandContent;\n\nCommand.Separator = CommandSeparator;\nCommand.List = CommandList;\nCommand.Group = CommandGroup;\nCommand.Empty = CommandEmpty;\nCommand.Input = CommandInput;\n\n// items\nCommand.Item = CommandItem;\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { cn } from "./classNames-DkX30VJU.js";
2
- import { Tooltip, copyToClipboard } from "./utils-DjFceY3H.js";
2
+ import { Tooltip, copyToClipboard } from "./utils-BxEJOnFD.js";
3
3
  import { Check, Copy, Eye, EyeOff } from "./icons-DDR9dFSr.js";
4
4
  import { Label } from "./internal/components/Label.js";
5
5
  import { createContext, use, useCallback, useEffect, useId, useMemo, useRef, useState } from "react";
@@ -271,4 +271,4 @@ const CopyField = {
271
271
  };
272
272
  export { CopyField };
273
273
 
274
- //# sourceMappingURL=CopyField-CnwAvQz9.js.map
274
+ //# sourceMappingURL=CopyField-9WBU8thS.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CopyField-CnwAvQz9.js","names":["CopyIcon"],"sources":["../src/blocks/CopyField/CopyContext.tsx","../src/blocks/CopyField/CopyBox.tsx","../src/blocks/CopyField/CopyButton.tsx","../src/blocks/CopyField/CopyChildren.tsx","../src/blocks/CopyField/CopyFooter.tsx","../src/blocks/CopyField/CopyHidden.tsx","../src/blocks/CopyField/CopyLabel.tsx","../src/blocks/CopyField/CopyPrefix.tsx","../src/blocks/CopyField/CopyReveal.tsx","../src/blocks/CopyField/CopyRoot.tsx","../src/blocks/CopyField/CopySuffix.tsx","../src/blocks/CopyField/CopyField.tsx"],"sourcesContent":["import { createContext, use } from 'react';\n\ntype CopyContextValue = {\n /** Whether a copy just happened (drives the Copy → Check feedback for ~1.5s). */\n copied: boolean;\n /** Copies the real `value` to the clipboard, guarded against drag-select. */\n handleCopy: () => void;\n /** The real value copied to the clipboard, regardless of masking. */\n value: string;\n /** Render displayed content in monospace/code style. */\n mono: boolean;\n /** Whether to show the \"Copy\" hint tooltip on hover (else only \"Copied\" on copy). */\n hoverHint: boolean;\n /** Whether revealable `CopyField.Hidden` content is currently masked. */\n hidden: boolean;\n /** Toggles the masked ↔ revealed state. */\n toggleHidden: () => void;\n /**\n * Registers a revealable `CopyField.Hidden` so `CopyField.Reveal` knows to render.\n * Returns a cleanup that unregisters on unmount.\n */\n registerRevealable: () => () => void;\n /** True once at least one revealable `CopyField.Hidden` is mounted. */\n hasRevealable: boolean;\n /**\n * Registers the visible `CopyField.Label` so `CopyField.Box` only points `aria-labelledby`\n * at it when a label actually exists. Returns a cleanup that unregisters on unmount.\n */\n registerLabel: () => () => void;\n /** True once a `CopyField.Label` is mounted. */\n hasLabel: boolean;\n /** Minimum number of visible text lines for a multi-line box. */\n minLines: number;\n /** Maximum number of visible text lines before the box scrolls. */\n maxLines: number;\n /** Stable id of the visible label element (for `aria-labelledby`). */\n labelId: string;\n /** Stable id of the clickable box element. */\n boxId: string;\n};\n\nexport const CopyContext = createContext<CopyContextValue | null>(null);\n\nexport const useCopyContext = () => {\n const ctx = use(CopyContext);\n if (!ctx) throw new Error('CopyField.* components must be used within a CopyField.Root');\n return ctx;\n};\n","import type { CSSProperties, KeyboardEvent, ReactNode } from 'react';\n\nimport { Tooltip } from '../../components/Tooltip';\nimport { cn } from '../../utils';\n\nimport { useCopyContext } from './CopyContext';\n\ntype CopyBoxProps = {\n /** Additional CSS classes on the box. */\n className?: string;\n children: ReactNode;\n};\n\nconst LINE_HEIGHT_REM = 1.25;\nconst VERTICAL_PADDING_REM = 1.25;\n\n// Long delay — the hover \"Copy\" hint doesn't really help UX, it just pulls focus.\nconst COPY_HINT_DELAY_MS = 2000;\n\n/**\n * The clickable copy target. Click anywhere to copy; text stays drag-selectable.\n *\n * Rendered as a `role=\"button\"` div (not a native `<button>`) so it can host\n * genuinely interactive children like `CopyField.Reveal` — nesting a `<button>`\n * inside a `<button>` is invalid HTML.\n */\nexport const CopyBox = ({ className, children }: CopyBoxProps) => {\n const { copied, handleCopy, mono, minLines, maxLines, boxId, labelId, hasLabel, hoverHint } =\n useCopyContext();\n\n const multiline = maxLines > 1;\n const multilineStyle: CSSProperties | undefined = multiline\n ? {\n minHeight: `${minLines * LINE_HEIGHT_REM + VERTICAL_PADDING_REM}rem`,\n maxHeight: `${maxLines * LINE_HEIGHT_REM + VERTICAL_PADDING_REM}rem`,\n }\n : undefined;\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (event.target !== event.currentTarget) return;\n if (event.key !== 'Enter' && event.key !== ' ') return;\n event.preventDefault();\n handleCopy();\n };\n\n return (\n <Tooltip\n triggerAsChild\n placement=\"top\"\n tooltip={copied ? 'Copied' : hoverHint ? 'Copy' : null}\n forceShow={copied}\n delayDuration={COPY_HINT_DELAY_MS}\n >\n <div\n role=\"button\"\n tabIndex={0}\n id={boxId}\n aria-labelledby={hasLabel ? labelId : undefined}\n onClick={handleCopy}\n onKeyDown={handleKeyDown}\n style={multilineStyle}\n className={cn(\n 'tw:group tw:relative tw:flex tw:w-fit tw:max-w-full tw:cursor-pointer tw:gap-2 tw:rounded-2xl tw:[corner-shape:superellipse(2)] tw:border tw:border-border tw:bg-card tw:px-3 tw:py-2.5 tw:text-left tw:shadow-sm tw:transition-colors tw:hover:bg-muted',\n multiline ? 'tw:items-start tw:overflow-auto' : 'tw:items-center tw:overflow-hidden',\n mono && 'tw:font-mono tw:text-[13px]',\n className,\n )}\n >\n {children}\n </div>\n </Tooltip>\n );\n};\n","import { Check, Copy as CopyIcon } from '../../icons';\nimport { cn } from '../../utils';\n\nimport { useCopyContext } from './CopyContext';\n\ntype CopyButtonProps = {\n className?: string;\n};\n\n/** Copy affordance icon — shows Copy/Check with feedback. */\nexport const CopyButton = ({ className }: CopyButtonProps) => {\n const { copied, maxLines } = useCopyContext();\n\n return (\n <span\n aria-hidden\n className={cn(\n 'tw:pointer-events-none tw:flex tw:shrink-0 tw:items-center tw:text-muted-foreground tw:group-hover:text-foreground',\n maxLines > 1 && 'tw:self-start tw:pt-0.5',\n className,\n )}\n >\n {copied ? <Check className=\"tw:size-4\" /> : <CopyIcon className=\"tw:size-4\" />}\n </span>\n );\n};\n","import type { ReactNode } from 'react';\n\nimport { cn } from '../../utils';\n\nimport { useCopyContext } from './CopyContext';\n\ntype CopyChildrenProps = {\n children: ReactNode;\n className?: string;\n};\n\n/** The displayed value. Truncates on a single line, wraps when multi-line. */\nexport const CopyChildren = ({ children, className }: CopyChildrenProps) => {\n const { maxLines } = useCopyContext();\n const multiline = maxLines > 1;\n\n return (\n <span\n className={cn(\n 'tw:min-w-0 tw:flex-1 tw:select-text tw:text-card-foreground',\n multiline ? 'tw:whitespace-pre-wrap tw:break-words' : 'tw:truncate',\n className,\n )}\n >\n {children}\n </span>\n );\n};\n","import type { ReactNode } from 'react';\n\nimport { cn } from '../../utils';\n\ntype CopyFooterProps = {\n children: ReactNode;\n className?: string;\n};\n\n/** Small helper text below the box (mirrors `FormGroup.Help` / `HelpBlock` styling). */\nexport const CopyFooter = ({ children, className }: CopyFooterProps) => {\n if (!children) return null;\n\n return <p className={cn('tw:m-0 tw:text-xs tw:text-muted-foreground', className)}>{children}</p>;\n};\n","import { useEffect } from 'react';\nimport type { ReactNode } from 'react';\n\nimport { cn } from '../../utils';\n\nimport { useCopyContext } from './CopyContext';\n\ntype CopyHiddenProps = {\n children: ReactNode;\n /**\n * When true (default), `CopyField.Reveal` can unmask this content. When false the\n * content is always masked (e.g. an implicit token inside a longer string).\n */\n revealable?: boolean;\n className?: string;\n};\n\nconst MASK = '*'.repeat(12);\n\n/**\n * Masks its children with asterisks. The real value still lives on `CopyField.Root`,\n * so copy always copies the real value regardless of mask state.\n */\nexport const CopyHidden = ({ children, revealable = true, className }: CopyHiddenProps) => {\n const { hidden, registerRevealable } = useCopyContext();\n\n useEffect(() => {\n if (!revealable) return undefined;\n return registerRevealable();\n }, [revealable, registerRevealable]);\n\n const masked = revealable ? hidden : true;\n\n return <span className={cn('tw:select-none', className)}>{masked ? MASK : children}</span>;\n};\n","import { useEffect } from 'react';\nimport type { ReactNode } from 'react';\n\nimport { Label } from '../../components/Label';\nimport { cn } from '../../utils';\n\nimport { useCopyContext } from './CopyContext';\n\ntype CopyLabelProps = {\n children: ReactNode;\n /** Content rendered right after the label text (e.g. an Info tooltip button). */\n leading?: ReactNode;\n /** Content pushed to the trailing edge of the row (e.g. a Switch). */\n trailing?: ReactNode;\n className?: string;\n};\n\n/**\n * Visible label above the box. The label carries an id and the box is wired via\n * `aria-labelledby` (not `htmlFor`, which would turn label clicks into a copy).\n *\n * Row layout: label text, then `leading` (gap), then `trailing` pushed to the far\n * edge with the space between them growing.\n */\nexport const CopyLabel = ({ children, leading, trailing, className }: CopyLabelProps) => {\n const { labelId, registerLabel } = useCopyContext();\n\n useEffect(() => registerLabel(), [registerLabel]);\n\n return (\n <div className={cn('tw:flex tw:items-center tw:gap-1', className)}>\n <Label id={labelId}>{children}</Label>\n {leading}\n {trailing != null && <span className=\"tw:ml-auto tw:flex tw:items-center\">{trailing}</span>}\n </div>\n );\n};\n","import type { ReactNode } from 'react';\n\nimport { cn } from '../../utils';\n\ntype CopyAddonProps = {\n children: ReactNode;\n className?: string;\n};\n\n/** Muted, non-selectable prefix addon with a trailing divider (not part of the copied value). */\nexport const CopyPrefix = ({ children, className }: CopyAddonProps) => (\n <span\n aria-hidden\n className={cn(\n 'tw:shrink-0 tw:select-none tw:self-stretch tw:border-r tw:border-border tw:pr-2 tw:text-muted-foreground',\n className,\n )}\n >\n {children}\n </span>\n);\n","import type { MouseEvent } from 'react';\n\nimport { Eye, EyeOff } from '../../icons';\nimport { cn } from '../../utils';\n\nimport { useCopyContext } from './CopyContext';\n\ntype CopyRevealProps = {\n className?: string;\n /** Names what the eye reveals, e.g. `password` → \"Show password\"; defaults to `value`. */\n subject?: string;\n};\n\n/** Eye toggle that reveals/masks `CopyField.Hidden` content. Renders nothing without revealable content. */\nexport const CopyReveal = ({ className, subject = 'value' }: CopyRevealProps) => {\n const { hidden, toggleHidden, hasRevealable, maxLines } = useCopyContext();\n\n if (!hasRevealable) return null;\n\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n event.stopPropagation();\n toggleHidden();\n };\n\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n aria-label={`${hidden ? 'Show' : 'Hide'} ${subject}`}\n className={cn(\n 'tw:flex tw:shrink-0 tw:items-center tw:text-muted-foreground tw:hover:text-foreground',\n maxLines > 1 && 'tw:self-start tw:pt-0.5',\n className,\n )}\n >\n {hidden ? <Eye className=\"tw:size-4\" /> : <EyeOff className=\"tw:size-4\" />}\n </button>\n );\n};\n","import { useCallback, useEffect, useId, useMemo, useRef, useState } from 'react';\nimport type { ReactNode } from 'react';\n\nimport { cn, copyToClipboard } from '../../utils';\n\nimport { CopyContext } from './CopyContext';\n\ntype CopyRootProps = {\n /** The value copied to the clipboard on click. */\n value: string;\n /** Render displayed content in monospace/code style. */\n mono?: boolean;\n /** Callback fired after a successful copy. */\n onCopy?: () => void;\n /** Start with revealable `CopyField.Hidden` content masked. */\n hiddenByDefault?: boolean;\n /** Minimum number of visible text lines for a multi-line box. */\n minLines?: number;\n /** Maximum number of visible text lines before the box scrolls. */\n maxLines?: number;\n /** Show the \"Copy\" hover hint (set `false` to only show \"Copied\" on copy). Defaults to `true`. */\n hoverHint?: boolean;\n /** Additional CSS classes on the outer container. */\n className?: string;\n children: ReactNode;\n};\n\n/**\n * Container for the Copy block. Owns the copied `value`, copy/mask state, and the\n * shared context consumed by `CopyField.Box`, `CopyField.Reveal`, `CopyField.Button`, etc.\n */\nexport const CopyRoot = ({\n value,\n mono = false,\n onCopy,\n hiddenByDefault = false,\n minLines = 1,\n maxLines,\n hoverHint = true,\n className,\n children,\n}: CopyRootProps) => {\n const [copied, setCopied] = useState(false);\n const [hidden, setHidden] = useState(hiddenByDefault);\n const [revealableCount, setRevealableCount] = useState(0);\n const [labelCount, setLabelCount] = useState(0);\n const resetTimerRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n\n const generatedId = useId();\n const labelId = `${generatedId}-label`;\n const boxId = `${generatedId}-box`;\n\n useEffect(() => () => clearTimeout(resetTimerRef.current), []);\n\n const handleCopy = useCallback(() => {\n const selection = window.getSelection();\n const boxEl = document.getElementById(boxId);\n if (\n selection &&\n !selection.isCollapsed &&\n selection.anchorNode &&\n boxEl?.contains(selection.anchorNode)\n ) {\n return;\n }\n\n copyToClipboard(value)\n .then(() => {\n onCopy?.();\n setCopied(true);\n clearTimeout(resetTimerRef.current);\n resetTimerRef.current = setTimeout(() => setCopied(false), 1500);\n })\n .catch((error: unknown) => {\n // eslint-disable-next-line no-console\n console.error('Copy to clipboard failed', error);\n });\n }, [value, onCopy, boxId]);\n\n const toggleHidden = useCallback(() => setHidden((prev) => !prev), []);\n\n const registerRevealable = useCallback(() => {\n setRevealableCount((count) => count + 1);\n return () => setRevealableCount((count) => count - 1);\n }, []);\n\n const registerLabel = useCallback(() => {\n setLabelCount((count) => count + 1);\n return () => setLabelCount((count) => count - 1);\n }, []);\n\n const contextValue = useMemo(\n () => ({\n copied,\n handleCopy,\n value,\n mono,\n hidden,\n toggleHidden,\n registerRevealable,\n hasRevealable: revealableCount > 0,\n registerLabel,\n hasLabel: labelCount > 0,\n minLines,\n maxLines: maxLines ?? minLines,\n hoverHint,\n labelId,\n boxId,\n }),\n [\n copied,\n handleCopy,\n value,\n mono,\n hidden,\n toggleHidden,\n registerRevealable,\n revealableCount,\n registerLabel,\n labelCount,\n minLines,\n maxLines,\n hoverHint,\n labelId,\n boxId,\n ],\n );\n\n return (\n <CopyContext value={contextValue}>\n <div className={cn('tw:flex tw:w-fit tw:max-w-full tw:flex-col tw:gap-1', className)}>\n {children}\n </div>\n </CopyContext>\n );\n};\n","import type { ReactNode } from 'react';\n\nimport { cn } from '../../utils';\n\ntype CopyAddonProps = {\n children: ReactNode;\n className?: string;\n};\n\n/** Muted, non-selectable suffix addon with a leading divider (not part of the copied value). */\nexport const CopySuffix = ({ children, className }: CopyAddonProps) => (\n <span\n aria-hidden\n className={cn(\n 'tw:shrink-0 tw:select-none tw:self-stretch tw:border-l tw:border-border tw:pl-2 tw:text-muted-foreground',\n className,\n )}\n >\n {children}\n </span>\n);\n","import { CopyBox } from './CopyBox';\nimport { CopyButton } from './CopyButton';\nimport { CopyChildren } from './CopyChildren';\nimport { CopyFooter } from './CopyFooter';\nimport { CopyHidden } from './CopyHidden';\nimport { CopyLabel } from './CopyLabel';\nimport { CopyPrefix } from './CopyPrefix';\nimport { CopyReveal } from './CopyReveal';\nimport { CopyRoot } from './CopyRoot';\nimport { CopySuffix } from './CopySuffix';\n\n/**\n * Readonly value/command box that copies `value` on click.\n *\n * - A click that ends a text selection does not copy.\n * - `mono` for commands; `maxLines > 1` wraps and scrolls between `minLines` and `maxLines`.\n * - `CopyField.Hidden` masks content; copy still copies the real `value`.\n */\nexport const CopyField = {\n /** Owns `value`, mask and copy state. */\n Root: CopyRoot,\n /** Label above the box, with `leading`/`trailing` slots. */\n Label: CopyLabel,\n /** The clickable copy target. */\n Box: CopyBox,\n /** Not copied. */\n Prefix: CopyPrefix,\n /** The displayed value. */\n Children: CopyChildren,\n /** Not copied. */\n Suffix: CopySuffix,\n /** Masked display only; copy still copies the real value. */\n Hidden: CopyHidden,\n /** Toggles revealable `CopyField.Hidden` content. */\n Reveal: CopyReveal,\n /** Copy icon with Copy → Check feedback. */\n Button: CopyButton,\n /** Helper text below the box. */\n Footer: CopyFooter,\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"CopyField-9WBU8thS.js","names":["CopyIcon"],"sources":["../src/blocks/CopyField/CopyContext.tsx","../src/blocks/CopyField/CopyBox.tsx","../src/blocks/CopyField/CopyButton.tsx","../src/blocks/CopyField/CopyChildren.tsx","../src/blocks/CopyField/CopyFooter.tsx","../src/blocks/CopyField/CopyHidden.tsx","../src/blocks/CopyField/CopyLabel.tsx","../src/blocks/CopyField/CopyPrefix.tsx","../src/blocks/CopyField/CopyReveal.tsx","../src/blocks/CopyField/CopyRoot.tsx","../src/blocks/CopyField/CopySuffix.tsx","../src/blocks/CopyField/CopyField.tsx"],"sourcesContent":["import { createContext, use } from 'react';\n\ntype CopyContextValue = {\n /** Whether a copy just happened (drives the Copy → Check feedback for ~1.5s). */\n copied: boolean;\n /** Copies the real `value` to the clipboard, guarded against drag-select. */\n handleCopy: () => void;\n /** The real value copied to the clipboard, regardless of masking. */\n value: string;\n /** Render displayed content in monospace/code style. */\n mono: boolean;\n /** Whether to show the \"Copy\" hint tooltip on hover (else only \"Copied\" on copy). */\n hoverHint: boolean;\n /** Whether revealable `CopyField.Hidden` content is currently masked. */\n hidden: boolean;\n /** Toggles the masked ↔ revealed state. */\n toggleHidden: () => void;\n /**\n * Registers a revealable `CopyField.Hidden` so `CopyField.Reveal` knows to render.\n * Returns a cleanup that unregisters on unmount.\n */\n registerRevealable: () => () => void;\n /** True once at least one revealable `CopyField.Hidden` is mounted. */\n hasRevealable: boolean;\n /**\n * Registers the visible `CopyField.Label` so `CopyField.Box` only points `aria-labelledby`\n * at it when a label actually exists. Returns a cleanup that unregisters on unmount.\n */\n registerLabel: () => () => void;\n /** True once a `CopyField.Label` is mounted. */\n hasLabel: boolean;\n /** Minimum number of visible text lines for a multi-line box. */\n minLines: number;\n /** Maximum number of visible text lines before the box scrolls. */\n maxLines: number;\n /** Stable id of the visible label element (for `aria-labelledby`). */\n labelId: string;\n /** Stable id of the clickable box element. */\n boxId: string;\n};\n\nexport const CopyContext = createContext<CopyContextValue | null>(null);\n\nexport const useCopyContext = () => {\n const ctx = use(CopyContext);\n if (!ctx) throw new Error('CopyField.* components must be used within a CopyField.Root');\n return ctx;\n};\n","import type { CSSProperties, KeyboardEvent, ReactNode } from 'react';\n\nimport { Tooltip } from '../../components/Tooltip';\nimport { cn } from '../../utils';\n\nimport { useCopyContext } from './CopyContext';\n\ntype CopyBoxProps = {\n /** Additional CSS classes on the box. */\n className?: string;\n children: ReactNode;\n};\n\nconst LINE_HEIGHT_REM = 1.25;\nconst VERTICAL_PADDING_REM = 1.25;\n\n// Long delay — the hover \"Copy\" hint doesn't really help UX, it just pulls focus.\nconst COPY_HINT_DELAY_MS = 2000;\n\n/**\n * The clickable copy target. Click anywhere to copy; text stays drag-selectable.\n *\n * Rendered as a `role=\"button\"` div (not a native `<button>`) so it can host\n * genuinely interactive children like `CopyField.Reveal` — nesting a `<button>`\n * inside a `<button>` is invalid HTML.\n */\nexport const CopyBox = ({ className, children }: CopyBoxProps) => {\n const { copied, handleCopy, mono, minLines, maxLines, boxId, labelId, hasLabel, hoverHint } =\n useCopyContext();\n\n const multiline = maxLines > 1;\n const multilineStyle: CSSProperties | undefined = multiline\n ? {\n minHeight: `${minLines * LINE_HEIGHT_REM + VERTICAL_PADDING_REM}rem`,\n maxHeight: `${maxLines * LINE_HEIGHT_REM + VERTICAL_PADDING_REM}rem`,\n }\n : undefined;\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (event.target !== event.currentTarget) return;\n if (event.key !== 'Enter' && event.key !== ' ') return;\n event.preventDefault();\n handleCopy();\n };\n\n return (\n <Tooltip\n triggerAsChild\n placement=\"top\"\n tooltip={copied ? 'Copied' : hoverHint ? 'Copy' : null}\n forceShow={copied}\n delayDuration={COPY_HINT_DELAY_MS}\n >\n <div\n role=\"button\"\n tabIndex={0}\n id={boxId}\n aria-labelledby={hasLabel ? labelId : undefined}\n onClick={handleCopy}\n onKeyDown={handleKeyDown}\n style={multilineStyle}\n className={cn(\n 'tw:group tw:relative tw:flex tw:w-fit tw:max-w-full tw:cursor-pointer tw:gap-2 tw:rounded-2xl tw:[corner-shape:superellipse(2)] tw:border tw:border-border tw:bg-card tw:px-3 tw:py-2.5 tw:text-left tw:shadow-sm tw:transition-colors tw:hover:bg-muted',\n multiline ? 'tw:items-start tw:overflow-auto' : 'tw:items-center tw:overflow-hidden',\n mono && 'tw:font-mono tw:text-[13px]',\n className,\n )}\n >\n {children}\n </div>\n </Tooltip>\n );\n};\n","import { Check, Copy as CopyIcon } from '../../icons';\nimport { cn } from '../../utils';\n\nimport { useCopyContext } from './CopyContext';\n\ntype CopyButtonProps = {\n className?: string;\n};\n\n/** Copy affordance icon — shows Copy/Check with feedback. */\nexport const CopyButton = ({ className }: CopyButtonProps) => {\n const { copied, maxLines } = useCopyContext();\n\n return (\n <span\n aria-hidden\n className={cn(\n 'tw:pointer-events-none tw:flex tw:shrink-0 tw:items-center tw:text-muted-foreground tw:group-hover:text-foreground',\n maxLines > 1 && 'tw:self-start tw:pt-0.5',\n className,\n )}\n >\n {copied ? <Check className=\"tw:size-4\" /> : <CopyIcon className=\"tw:size-4\" />}\n </span>\n );\n};\n","import type { ReactNode } from 'react';\n\nimport { cn } from '../../utils';\n\nimport { useCopyContext } from './CopyContext';\n\ntype CopyChildrenProps = {\n children: ReactNode;\n className?: string;\n};\n\n/** The displayed value. Truncates on a single line, wraps when multi-line. */\nexport const CopyChildren = ({ children, className }: CopyChildrenProps) => {\n const { maxLines } = useCopyContext();\n const multiline = maxLines > 1;\n\n return (\n <span\n className={cn(\n 'tw:min-w-0 tw:flex-1 tw:select-text tw:text-card-foreground',\n multiline ? 'tw:whitespace-pre-wrap tw:break-words' : 'tw:truncate',\n className,\n )}\n >\n {children}\n </span>\n );\n};\n","import type { ReactNode } from 'react';\n\nimport { cn } from '../../utils';\n\ntype CopyFooterProps = {\n children: ReactNode;\n className?: string;\n};\n\n/** Small helper text below the box (mirrors `FormGroup.Help` / `HelpBlock` styling). */\nexport const CopyFooter = ({ children, className }: CopyFooterProps) => {\n if (!children) return null;\n\n return <p className={cn('tw:m-0 tw:text-xs tw:text-muted-foreground', className)}>{children}</p>;\n};\n","import { useEffect } from 'react';\nimport type { ReactNode } from 'react';\n\nimport { cn } from '../../utils';\n\nimport { useCopyContext } from './CopyContext';\n\ntype CopyHiddenProps = {\n children: ReactNode;\n /**\n * When true (default), `CopyField.Reveal` can unmask this content. When false the\n * content is always masked (e.g. an implicit token inside a longer string).\n */\n revealable?: boolean;\n className?: string;\n};\n\nconst MASK = '*'.repeat(12);\n\n/**\n * Masks its children with asterisks. The real value still lives on `CopyField.Root`,\n * so copy always copies the real value regardless of mask state.\n */\nexport const CopyHidden = ({ children, revealable = true, className }: CopyHiddenProps) => {\n const { hidden, registerRevealable } = useCopyContext();\n\n useEffect(() => {\n if (!revealable) return undefined;\n return registerRevealable();\n }, [revealable, registerRevealable]);\n\n const masked = revealable ? hidden : true;\n\n return <span className={cn('tw:select-none', className)}>{masked ? MASK : children}</span>;\n};\n","import { useEffect } from 'react';\nimport type { ReactNode } from 'react';\n\nimport { Label } from '../../components/Label';\nimport { cn } from '../../utils';\n\nimport { useCopyContext } from './CopyContext';\n\ntype CopyLabelProps = {\n children: ReactNode;\n /** Content rendered right after the label text (e.g. an Info tooltip button). */\n leading?: ReactNode;\n /** Content pushed to the trailing edge of the row (e.g. a Switch). */\n trailing?: ReactNode;\n className?: string;\n};\n\n/**\n * Visible label above the box. The label carries an id and the box is wired via\n * `aria-labelledby` (not `htmlFor`, which would turn label clicks into a copy).\n *\n * Row layout: label text, then `leading` (gap), then `trailing` pushed to the far\n * edge with the space between them growing.\n */\nexport const CopyLabel = ({ children, leading, trailing, className }: CopyLabelProps) => {\n const { labelId, registerLabel } = useCopyContext();\n\n useEffect(() => registerLabel(), [registerLabel]);\n\n return (\n <div className={cn('tw:flex tw:items-center tw:gap-1', className)}>\n <Label id={labelId}>{children}</Label>\n {leading}\n {trailing != null && <span className=\"tw:ml-auto tw:flex tw:items-center\">{trailing}</span>}\n </div>\n );\n};\n","import type { ReactNode } from 'react';\n\nimport { cn } from '../../utils';\n\ntype CopyAddonProps = {\n children: ReactNode;\n className?: string;\n};\n\n/** Muted, non-selectable prefix addon with a trailing divider (not part of the copied value). */\nexport const CopyPrefix = ({ children, className }: CopyAddonProps) => (\n <span\n aria-hidden\n className={cn(\n 'tw:shrink-0 tw:select-none tw:self-stretch tw:border-r tw:border-border tw:pr-2 tw:text-muted-foreground',\n className,\n )}\n >\n {children}\n </span>\n);\n","import type { MouseEvent } from 'react';\n\nimport { Eye, EyeOff } from '../../icons';\nimport { cn } from '../../utils';\n\nimport { useCopyContext } from './CopyContext';\n\ntype CopyRevealProps = {\n className?: string;\n /** Names what the eye reveals, e.g. `password` → \"Show password\"; defaults to `value`. */\n subject?: string;\n};\n\n/** Eye toggle that reveals/masks `CopyField.Hidden` content. Renders nothing without revealable content. */\nexport const CopyReveal = ({ className, subject = 'value' }: CopyRevealProps) => {\n const { hidden, toggleHidden, hasRevealable, maxLines } = useCopyContext();\n\n if (!hasRevealable) return null;\n\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n event.stopPropagation();\n toggleHidden();\n };\n\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n aria-label={`${hidden ? 'Show' : 'Hide'} ${subject}`}\n className={cn(\n 'tw:flex tw:shrink-0 tw:items-center tw:text-muted-foreground tw:hover:text-foreground',\n maxLines > 1 && 'tw:self-start tw:pt-0.5',\n className,\n )}\n >\n {hidden ? <Eye className=\"tw:size-4\" /> : <EyeOff className=\"tw:size-4\" />}\n </button>\n );\n};\n","import { useCallback, useEffect, useId, useMemo, useRef, useState } from 'react';\nimport type { ReactNode } from 'react';\n\nimport { cn, copyToClipboard } from '../../utils';\n\nimport { CopyContext } from './CopyContext';\n\ntype CopyRootProps = {\n /** The value copied to the clipboard on click. */\n value: string;\n /** Render displayed content in monospace/code style. */\n mono?: boolean;\n /** Callback fired after a successful copy. */\n onCopy?: () => void;\n /** Start with revealable `CopyField.Hidden` content masked. */\n hiddenByDefault?: boolean;\n /** Minimum number of visible text lines for a multi-line box. */\n minLines?: number;\n /** Maximum number of visible text lines before the box scrolls. */\n maxLines?: number;\n /** Show the \"Copy\" hover hint (set `false` to only show \"Copied\" on copy). Defaults to `true`. */\n hoverHint?: boolean;\n /** Additional CSS classes on the outer container. */\n className?: string;\n children: ReactNode;\n};\n\n/**\n * Container for the Copy block. Owns the copied `value`, copy/mask state, and the\n * shared context consumed by `CopyField.Box`, `CopyField.Reveal`, `CopyField.Button`, etc.\n */\nexport const CopyRoot = ({\n value,\n mono = false,\n onCopy,\n hiddenByDefault = false,\n minLines = 1,\n maxLines,\n hoverHint = true,\n className,\n children,\n}: CopyRootProps) => {\n const [copied, setCopied] = useState(false);\n const [hidden, setHidden] = useState(hiddenByDefault);\n const [revealableCount, setRevealableCount] = useState(0);\n const [labelCount, setLabelCount] = useState(0);\n const resetTimerRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n\n const generatedId = useId();\n const labelId = `${generatedId}-label`;\n const boxId = `${generatedId}-box`;\n\n useEffect(() => () => clearTimeout(resetTimerRef.current), []);\n\n const handleCopy = useCallback(() => {\n const selection = window.getSelection();\n const boxEl = document.getElementById(boxId);\n if (\n selection &&\n !selection.isCollapsed &&\n selection.anchorNode &&\n boxEl?.contains(selection.anchorNode)\n ) {\n return;\n }\n\n copyToClipboard(value)\n .then(() => {\n onCopy?.();\n setCopied(true);\n clearTimeout(resetTimerRef.current);\n resetTimerRef.current = setTimeout(() => setCopied(false), 1500);\n })\n .catch((error: unknown) => {\n // eslint-disable-next-line no-console\n console.error('Copy to clipboard failed', error);\n });\n }, [value, onCopy, boxId]);\n\n const toggleHidden = useCallback(() => setHidden((prev) => !prev), []);\n\n const registerRevealable = useCallback(() => {\n setRevealableCount((count) => count + 1);\n return () => setRevealableCount((count) => count - 1);\n }, []);\n\n const registerLabel = useCallback(() => {\n setLabelCount((count) => count + 1);\n return () => setLabelCount((count) => count - 1);\n }, []);\n\n const contextValue = useMemo(\n () => ({\n copied,\n handleCopy,\n value,\n mono,\n hidden,\n toggleHidden,\n registerRevealable,\n hasRevealable: revealableCount > 0,\n registerLabel,\n hasLabel: labelCount > 0,\n minLines,\n maxLines: maxLines ?? minLines,\n hoverHint,\n labelId,\n boxId,\n }),\n [\n copied,\n handleCopy,\n value,\n mono,\n hidden,\n toggleHidden,\n registerRevealable,\n revealableCount,\n registerLabel,\n labelCount,\n minLines,\n maxLines,\n hoverHint,\n labelId,\n boxId,\n ],\n );\n\n return (\n <CopyContext value={contextValue}>\n <div className={cn('tw:flex tw:w-fit tw:max-w-full tw:flex-col tw:gap-1', className)}>\n {children}\n </div>\n </CopyContext>\n );\n};\n","import type { ReactNode } from 'react';\n\nimport { cn } from '../../utils';\n\ntype CopyAddonProps = {\n children: ReactNode;\n className?: string;\n};\n\n/** Muted, non-selectable suffix addon with a leading divider (not part of the copied value). */\nexport const CopySuffix = ({ children, className }: CopyAddonProps) => (\n <span\n aria-hidden\n className={cn(\n 'tw:shrink-0 tw:select-none tw:self-stretch tw:border-l tw:border-border tw:pl-2 tw:text-muted-foreground',\n className,\n )}\n >\n {children}\n </span>\n);\n","import { CopyBox } from './CopyBox';\nimport { CopyButton } from './CopyButton';\nimport { CopyChildren } from './CopyChildren';\nimport { CopyFooter } from './CopyFooter';\nimport { CopyHidden } from './CopyHidden';\nimport { CopyLabel } from './CopyLabel';\nimport { CopyPrefix } from './CopyPrefix';\nimport { CopyReveal } from './CopyReveal';\nimport { CopyRoot } from './CopyRoot';\nimport { CopySuffix } from './CopySuffix';\n\n/**\n * Readonly value/command box that copies `value` on click.\n *\n * - A click that ends a text selection does not copy.\n * - `mono` for commands; `maxLines > 1` wraps and scrolls between `minLines` and `maxLines`.\n * - `CopyField.Hidden` masks content; copy still copies the real `value`.\n */\nexport const CopyField = {\n /** Owns `value`, mask and copy state. */\n Root: CopyRoot,\n /** Label above the box, with `leading`/`trailing` slots. */\n Label: CopyLabel,\n /** The clickable copy target. */\n Box: CopyBox,\n /** Not copied. */\n Prefix: CopyPrefix,\n /** The displayed value. */\n Children: CopyChildren,\n /** Not copied. */\n Suffix: CopySuffix,\n /** Masked display only; copy still copies the real value. */\n Hidden: CopyHidden,\n /** Toggles revealable `CopyField.Hidden` content. */\n Reveal: CopyReveal,\n /** Copy icon with Copy → Check feedback. */\n Button: CopyButton,\n /** Helper text below the box. */\n Footer: CopyFooter,\n};\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
- import { createChangeInputEvent } from "./utils-DjFceY3H.js";
1
+ import { createChangeInputEvent } from "./utils-BxEJOnFD.js";
2
2
  import { mergeRefs } from "./internal/utils/mergeRefs.js";
3
3
  import { Calendar, X } from "./icons-DDR9dFSr.js";
4
- import { InputGroup } from "./InputGroup-BWeanEo7.js";
4
+ import { InputGroup } from "./InputGroup-DnGP9-ZQ.js";
5
5
  import { useControllableState } from "./useControllableState-BCvUOC6G.js";
6
6
  import { DatePicker } from "./DatePicker-CI59gF3S.js";
7
7
  import { useRef, useState } from "react";
@@ -134,4 +134,4 @@ const DateInput = ({ ref, state, focusVariant, className, value, defaultValue, o
134
134
  };
135
135
  export { DateInput };
136
136
 
137
- //# sourceMappingURL=DateInput-DJNX7Vdx.js.map
137
+ //# sourceMappingURL=DateInput-CCYG0AtT.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DateInput-DJNX7Vdx.js","names":["CalendarIcon"],"sources":["../src/blocks/DateInput/helpers.ts","../src/blocks/DateInput/DateInput.tsx"],"sourcesContent":["export const formatDate = (date: Date | null | undefined, inputValue: string): string => {\n if (!date) {\n return inputValue;\n }\n return date.toLocaleDateString();\n};\n\n// Detect locale day/month/year order once, matching toLocaleDateString() output\nconst datePartOrder = new Intl.DateTimeFormat()\n .formatToParts(new Date(2000, 0, 2))\n .filter(\n (p): p is { type: 'day' | 'month' | 'year'; value: string } =>\n p.type === 'day' || p.type === 'month' || p.type === 'year',\n )\n .map((p) => p.type);\n\nexport const parseDate = (value: string): Date | null => {\n if (!value.trim()) return null;\n\n // Try locale-aware parsing first (matches toLocaleDateString round-trip)\n const nums = value.match(/\\d+/g)?.map(Number);\n if (nums && nums.length >= 3) {\n const parts = Object.fromEntries(datePartOrder.map((type, i) => [type, nums[i]]));\n const year = parts.year;\n const month = parts.month;\n const day = parts.day;\n\n if (\n year != null &&\n month != null &&\n day != null &&\n month >= 1 &&\n month <= 12 &&\n day >= 1 &&\n day <= 31\n ) {\n const date = new Date(year, month - 1, day);\n if (date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day) {\n return date;\n }\n }\n }\n\n // Fallback: detect ISO YYYY-MM-DD and construct as local midnight to avoid UTC offset issues\n const isoMatch = value.match(/^(\\d{4})-(\\d{1,2})-(\\d{1,2})$/);\n if (isoMatch) {\n const y = Number(isoMatch[1]);\n const m = Number(isoMatch[2]) - 1;\n const d = Number(isoMatch[3]);\n const date = new Date(y, m, d);\n if (date.getFullYear() === y && date.getMonth() === m && date.getDate() === d) {\n return date;\n }\n return null;\n }\n\n const fallback = new Date(value);\n return isNaN(fallback.getTime()) ? null : fallback;\n};\n","import { useRef, useState } from 'react';\nimport type {\n ChangeEventHandler,\n ComponentProps,\n ComponentRef,\n FocusEventHandler,\n MouseEventHandler,\n} from 'react';\nimport type { Matcher } from 'react-day-picker';\n\nimport { DatePicker } from '../../components/DatePicker';\nimport { InputGroup } from '../../components/InputGroup';\nimport { useControllableState } from '../../hooks/useControllableState';\nimport { Calendar as CalendarIcon, X } from '../../icons';\nimport { createChangeInputEvent, mergeRefs } from '../../utils';\n\nimport { formatDate, parseDate } from './helpers';\n\ntype InputGroupProps = Pick<ComponentProps<typeof InputGroup>, 'focusVariant' | 'state'>;\n\ntype InputGroupInputProps = Omit<\n ComponentProps<typeof InputGroup.Input>,\n 'value' | 'defaultValue' | 'type'\n>;\n\ntype Props = InputGroupProps &\n InputGroupInputProps & {\n value?: Date | null;\n defaultValue?: Date | null;\n onValueChange?: (value: Date | null) => void;\n onValueBlur?: (value: Date | null) => void;\n allowClear?: boolean;\n disabledDays?: Matcher | Matcher[];\n endMonth?: Date;\n startMonth?: Date;\n };\n\nexport const DateInput = ({\n ref,\n\n // group props\n state,\n focusVariant,\n className,\n\n // own props\n value,\n defaultValue,\n onValueChange,\n onValueBlur,\n onChange,\n onBlur,\n onFocus,\n allowClear = false,\n disabledDays,\n endMonth,\n startMonth,\n\n // input props\n disabled,\n readOnly,\n placeholder = 'Select a date',\n ...restInputProps\n}: Props) => {\n const inputRef = useRef<ComponentRef<'input'>>(null);\n\n const [inputValue, setInputValue] = useState('');\n const [hasFocus, setHasFocus] = useState(false);\n const [isOpen, setIsOpen] = useState(false);\n const [month, setMonth] = useState<Date>(new Date());\n\n // `onValueChange` is fired explicitly per-path below (not through the hook), because commits\n // happen on blur / picker-select rather than on every keystroke.\n const [currentValue, setCurrentValue] = useControllableState<Date | null>({\n prop: value,\n defaultProp: defaultValue ?? null,\n });\n\n const canClear = allowClear && !!currentValue && !disabled && !readOnly;\n const showPicker = !disabled && !readOnly;\n\n const handleChange: ChangeEventHandler<HTMLInputElement> = (event) => {\n const newValue = event.target.value;\n setInputValue(newValue);\n onChange?.(event);\n\n const parsedDate = parseDate(newValue);\n if (parsedDate !== null || !newValue.trim()) {\n onValueChange?.(parsedDate);\n }\n };\n\n const handleFocus: FocusEventHandler<HTMLInputElement> = (event) => {\n const formatted = formatDate(currentValue, '');\n setInputValue(formatted);\n setHasFocus(true);\n onFocus?.(event);\n };\n\n const handleBlur: FocusEventHandler<HTMLInputElement> = (event) => {\n setHasFocus(false);\n onBlur?.(event);\n\n // If the field still shows the formatted current value (focused and blurred\n // without editing), keep it as-is. `formatDate` uses `toLocaleDateString`,\n // whose output is not reliably parseable by `parseDate` in every locale, so\n // round-tripping an untouched value could wrongly null it.\n const text = event.target.value;\n const parsedDate = text === formatDate(currentValue, '') ? currentValue : parseDate(text);\n onValueBlur?.(parsedDate);\n\n setCurrentValue(parsedDate);\n };\n\n const handleDatePickerChange = (newValue?: Date) => {\n const dateValue = newValue ?? null;\n\n setCurrentValue(dateValue);\n onValueChange?.(dateValue);\n\n setHasFocus(false);\n setIsOpen(false);\n };\n\n const handleClear: MouseEventHandler<HTMLButtonElement> = () => {\n if (!inputRef.current) return;\n inputRef.current.value = '';\n setInputValue('');\n setCurrentValue(null);\n onValueChange?.(null);\n onChange?.(createChangeInputEvent(inputRef.current));\n };\n\n const handleOpenChange = (open: boolean) => {\n if (open) {\n setMonth(currentValue ?? new Date());\n }\n setIsOpen(open);\n };\n\n const displayValue = hasFocus ? inputValue : formatDate(currentValue, '');\n\n return (\n <InputGroup state={state} focusVariant={focusVariant} className={className}>\n <InputGroup.Input\n {...restInputProps}\n ref={mergeRefs(ref ?? null, inputRef)}\n type=\"text\"\n value={displayValue}\n placeholder={placeholder}\n onChange={handleChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n disabled={disabled}\n readOnly={readOnly}\n />\n\n {(canClear || showPicker) && (\n <InputGroup.Addon align=\"inline-end\">\n {canClear && (\n <InputGroup.Button\n aria-label=\"Clear date\"\n onMouseDown={(event) => event.preventDefault()}\n onClick={handleClear}\n >\n <X className=\"tw:size-4\" />\n </InputGroup.Button>\n )}\n {showPicker && (\n <DatePicker\n disabled={disabledDays}\n endMonth={endMonth}\n mode=\"single\"\n month={month}\n onMonthChange={setMonth}\n onOpenChange={handleOpenChange}\n onSelect={handleDatePickerChange}\n open={isOpen}\n selected={currentValue ?? undefined}\n startMonth={startMonth}\n >\n <InputGroup.Button aria-label=\"Select Date\">\n <CalendarIcon className=\"tw:size-4\" />\n </InputGroup.Button>\n </DatePicker>\n )}\n </InputGroup.Addon>\n )}\n </InputGroup>\n );\n};\n"],"mappings":";;;;;;;;;AAAA,MAAa,cAAc,MAA+B,eAA+B;CACvF,IAAI,CAAC,MACH,OAAO;CAET,OAAO,KAAK,mBAAmB;AACjC;AAGA,MAAM,gBAAgB,IAAI,KAAK,eAAe,CAAC,CAC5C,cAAc,IAAI,KAAK,KAAM,GAAG,CAAC,CAAC,CAAC,CACnC,QACE,MACC,EAAE,SAAS,SAAS,EAAE,SAAS,WAAW,EAAE,SAAS,MACzD,CAAC,CACA,KAAK,MAAM,EAAE,IAAI;AAEpB,MAAa,aAAa,UAA+B;CACvD,IAAI,CAAC,MAAM,KAAK,GAAG,OAAO;CAG1B,MAAM,OAAO,MAAM,MAAM,MAAM,CAAC,EAAE,IAAI,MAAM;CAC5C,IAAI,QAAQ,KAAK,UAAU,GAAG;EAC5B,MAAM,QAAQ,OAAO,YAAY,cAAc,KAAK,MAAM,MAAM,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC;EAChF,MAAM,OAAO,MAAM;EACnB,MAAM,QAAQ,MAAM;EACpB,MAAM,MAAM,MAAM;EAElB,IACE,QAAQ,QACR,SAAS,QACT,OAAO,QACP,SAAS,KACT,SAAS,MACT,OAAO,KACP,OAAO,IACP;GACA,MAAM,OAAO,IAAI,KAAK,MAAM,QAAQ,GAAG,GAAG;GAC1C,IAAI,KAAK,YAAY,MAAM,QAAQ,KAAK,SAAS,MAAM,QAAQ,KAAK,KAAK,QAAQ,MAAM,KACrF,OAAO;EAEX;CACF;CAGA,MAAM,WAAW,MAAM,MAAM,+BAA+B;CAC5D,IAAI,UAAU;EACZ,MAAM,IAAI,OAAO,SAAS,EAAE;EAC5B,MAAM,IAAI,OAAO,SAAS,EAAE,IAAI;EAChC,MAAM,IAAI,OAAO,SAAS,EAAE;EAC5B,MAAM,OAAO,IAAI,KAAK,GAAG,GAAG,CAAC;EAC7B,IAAI,KAAK,YAAY,MAAM,KAAK,KAAK,SAAS,MAAM,KAAK,KAAK,QAAQ,MAAM,GAC1E,OAAO;EAET,OAAO;CACT;CAEA,MAAM,WAAW,IAAI,KAAK,KAAK;CAC/B,OAAO,MAAM,SAAS,QAAQ,CAAC,IAAI,OAAO;AAC5C;;ACrBA,MAAa,aAAa,EACxB,KAGA,OACA,cACA,WAGA,OACA,cACA,eACA,aACA,UACA,QACA,SACA,aAAa,OACb,cACA,UACA,YAGA,UACA,UACA,cAAc,iBACd,GAAG,qBACQ;CACX,MAAM,WAAW,OAA8B,IAAI;CAEnD,MAAM,CAAC,YAAY,iBAAiB,SAAS,EAAE;CAC/C,MAAM,CAAC,UAAU,eAAe,SAAS,KAAK;CAC9C,MAAM,CAAC,QAAQ,aAAa,SAAS,KAAK;CAC1C,MAAM,CAAC,OAAO,YAAY,yBAAe,IAAI,KAAK,CAAC;CAInD,MAAM,CAAC,cAAc,mBAAmB,qBAAkC;EACxE,MAAM;EACN,aAAa,gBAAgB;CAC/B,CAAC;CAED,MAAM,WAAW,cAAc,CAAC,CAAC,gBAAgB,CAAC,YAAY,CAAC;CAC/D,MAAM,aAAa,CAAC,YAAY,CAAC;CAEjC,MAAM,gBAAsD,UAAU;EACpE,MAAM,WAAW,MAAM,OAAO;EAC9B,cAAc,QAAQ;EACtB,WAAW,KAAK;EAEhB,MAAM,aAAa,UAAU,QAAQ;EACrC,IAAI,eAAe,QAAQ,CAAC,SAAS,KAAK,GACxC,gBAAgB,UAAU;CAE9B;CAEA,MAAM,eAAoD,UAAU;EAClE,MAAM,YAAY,WAAW,cAAc,EAAE;EAC7C,cAAc,SAAS;EACvB,YAAY,IAAI;EAChB,UAAU,KAAK;CACjB;CAEA,MAAM,cAAmD,UAAU;EACjE,YAAY,KAAK;EACjB,SAAS,KAAK;EAMd,MAAM,OAAO,MAAM,OAAO;EAC1B,MAAM,aAAa,SAAS,WAAW,cAAc,EAAE,IAAI,eAAe,UAAU,IAAI;EACxF,cAAc,UAAU;EAExB,gBAAgB,UAAU;CAC5B;CAEA,MAAM,0BAA0B,aAAoB;EAClD,MAAM,YAAY,YAAY;EAE9B,gBAAgB,SAAS;EACzB,gBAAgB,SAAS;EAEzB,YAAY,KAAK;EACjB,UAAU,KAAK;CACjB;CAEA,MAAM,oBAA0D;EAC9D,IAAI,CAAC,SAAS,SAAS;EACvB,SAAS,QAAQ,QAAQ;EACzB,cAAc,EAAE;EAChB,gBAAgB,IAAI;EACpB,gBAAgB,IAAI;EACpB,WAAW,uBAAuB,SAAS,OAAO,CAAC;CACrD;CAEA,MAAM,oBAAoB,SAAkB;EAC1C,IAAI,MACF,SAAS,gCAAgB,IAAI,KAAK,CAAC;EAErC,UAAU,IAAI;CAChB;CAEA,MAAM,eAAe,WAAW,aAAa,WAAW,cAAc,EAAE;CAExE,OACE,qBAAC,YAAD;EAAmB;EAAqB;EAAyB;EAAjE,UAAA,CACE,oBAAC,WAAW,OAAZ;GACE,GAAI;GACJ,KAAK,UAAU,OAAO,MAAM,QAAQ;GACpC,MAAK;GACL,OAAO;GACM;GACb,UAAU;GACV,SAAS;GACT,QAAQ;GACE;GACA;EACX,CAAA,IAEC,YAAY,eACZ,qBAAC,WAAW,OAAZ;GAAkB,OAAM;GAAxB,UAAA,CACG,YACC,oBAAC,WAAW,QAAZ;IACE,cAAW;IACX,cAAc,UAAU,MAAM,eAAe;IAC7C,SAAS;IAET,UAAA,oBAAC,GAAD,EAAG,WAAU,YAAa,CAAA;GACT,CAAA,GAEpB,cACC,oBAAC,YAAD;IACE,UAAU;IACA;IACV,MAAK;IACE;IACP,eAAe;IACf,cAAc;IACd,UAAU;IACV,MAAM;IACN,UAAU,gBAAgB,KAAA;IACd;IAEZ,UAAA,oBAAC,WAAW,QAAZ;KAAmB,cAAW;KAC5B,UAAA,oBAACA,UAAD,EAAc,WAAU,YAAa,CAAA;IACpB,CAAA;GACT,CAAA,CAEE;EAEV,CAAA,CAAA;;AAEhB"}
1
+ {"version":3,"file":"DateInput-CCYG0AtT.js","names":["CalendarIcon"],"sources":["../src/blocks/DateInput/helpers.ts","../src/blocks/DateInput/DateInput.tsx"],"sourcesContent":["export const formatDate = (date: Date | null | undefined, inputValue: string): string => {\n if (!date) {\n return inputValue;\n }\n return date.toLocaleDateString();\n};\n\n// Detect locale day/month/year order once, matching toLocaleDateString() output\nconst datePartOrder = new Intl.DateTimeFormat()\n .formatToParts(new Date(2000, 0, 2))\n .filter(\n (p): p is { type: 'day' | 'month' | 'year'; value: string } =>\n p.type === 'day' || p.type === 'month' || p.type === 'year',\n )\n .map((p) => p.type);\n\nexport const parseDate = (value: string): Date | null => {\n if (!value.trim()) return null;\n\n // Try locale-aware parsing first (matches toLocaleDateString round-trip)\n const nums = value.match(/\\d+/g)?.map(Number);\n if (nums && nums.length >= 3) {\n const parts = Object.fromEntries(datePartOrder.map((type, i) => [type, nums[i]]));\n const year = parts.year;\n const month = parts.month;\n const day = parts.day;\n\n if (\n year != null &&\n month != null &&\n day != null &&\n month >= 1 &&\n month <= 12 &&\n day >= 1 &&\n day <= 31\n ) {\n const date = new Date(year, month - 1, day);\n if (date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day) {\n return date;\n }\n }\n }\n\n // Fallback: detect ISO YYYY-MM-DD and construct as local midnight to avoid UTC offset issues\n const isoMatch = value.match(/^(\\d{4})-(\\d{1,2})-(\\d{1,2})$/);\n if (isoMatch) {\n const y = Number(isoMatch[1]);\n const m = Number(isoMatch[2]) - 1;\n const d = Number(isoMatch[3]);\n const date = new Date(y, m, d);\n if (date.getFullYear() === y && date.getMonth() === m && date.getDate() === d) {\n return date;\n }\n return null;\n }\n\n const fallback = new Date(value);\n return isNaN(fallback.getTime()) ? null : fallback;\n};\n","import { useRef, useState } from 'react';\nimport type {\n ChangeEventHandler,\n ComponentProps,\n ComponentRef,\n FocusEventHandler,\n MouseEventHandler,\n} from 'react';\nimport type { Matcher } from 'react-day-picker';\n\nimport { DatePicker } from '../../components/DatePicker';\nimport { InputGroup } from '../../components/InputGroup';\nimport { useControllableState } from '../../hooks/useControllableState';\nimport { Calendar as CalendarIcon, X } from '../../icons';\nimport { createChangeInputEvent, mergeRefs } from '../../utils';\n\nimport { formatDate, parseDate } from './helpers';\n\ntype InputGroupProps = Pick<ComponentProps<typeof InputGroup>, 'focusVariant' | 'state'>;\n\ntype InputGroupInputProps = Omit<\n ComponentProps<typeof InputGroup.Input>,\n 'value' | 'defaultValue' | 'type'\n>;\n\ntype Props = InputGroupProps &\n InputGroupInputProps & {\n value?: Date | null;\n defaultValue?: Date | null;\n onValueChange?: (value: Date | null) => void;\n onValueBlur?: (value: Date | null) => void;\n allowClear?: boolean;\n disabledDays?: Matcher | Matcher[];\n endMonth?: Date;\n startMonth?: Date;\n };\n\nexport const DateInput = ({\n ref,\n\n // group props\n state,\n focusVariant,\n className,\n\n // own props\n value,\n defaultValue,\n onValueChange,\n onValueBlur,\n onChange,\n onBlur,\n onFocus,\n allowClear = false,\n disabledDays,\n endMonth,\n startMonth,\n\n // input props\n disabled,\n readOnly,\n placeholder = 'Select a date',\n ...restInputProps\n}: Props) => {\n const inputRef = useRef<ComponentRef<'input'>>(null);\n\n const [inputValue, setInputValue] = useState('');\n const [hasFocus, setHasFocus] = useState(false);\n const [isOpen, setIsOpen] = useState(false);\n const [month, setMonth] = useState<Date>(new Date());\n\n // `onValueChange` is fired explicitly per-path below (not through the hook), because commits\n // happen on blur / picker-select rather than on every keystroke.\n const [currentValue, setCurrentValue] = useControllableState<Date | null>({\n prop: value,\n defaultProp: defaultValue ?? null,\n });\n\n const canClear = allowClear && !!currentValue && !disabled && !readOnly;\n const showPicker = !disabled && !readOnly;\n\n const handleChange: ChangeEventHandler<HTMLInputElement> = (event) => {\n const newValue = event.target.value;\n setInputValue(newValue);\n onChange?.(event);\n\n const parsedDate = parseDate(newValue);\n if (parsedDate !== null || !newValue.trim()) {\n onValueChange?.(parsedDate);\n }\n };\n\n const handleFocus: FocusEventHandler<HTMLInputElement> = (event) => {\n const formatted = formatDate(currentValue, '');\n setInputValue(formatted);\n setHasFocus(true);\n onFocus?.(event);\n };\n\n const handleBlur: FocusEventHandler<HTMLInputElement> = (event) => {\n setHasFocus(false);\n onBlur?.(event);\n\n // If the field still shows the formatted current value (focused and blurred\n // without editing), keep it as-is. `formatDate` uses `toLocaleDateString`,\n // whose output is not reliably parseable by `parseDate` in every locale, so\n // round-tripping an untouched value could wrongly null it.\n const text = event.target.value;\n const parsedDate = text === formatDate(currentValue, '') ? currentValue : parseDate(text);\n onValueBlur?.(parsedDate);\n\n setCurrentValue(parsedDate);\n };\n\n const handleDatePickerChange = (newValue?: Date) => {\n const dateValue = newValue ?? null;\n\n setCurrentValue(dateValue);\n onValueChange?.(dateValue);\n\n setHasFocus(false);\n setIsOpen(false);\n };\n\n const handleClear: MouseEventHandler<HTMLButtonElement> = () => {\n if (!inputRef.current) return;\n inputRef.current.value = '';\n setInputValue('');\n setCurrentValue(null);\n onValueChange?.(null);\n onChange?.(createChangeInputEvent(inputRef.current));\n };\n\n const handleOpenChange = (open: boolean) => {\n if (open) {\n setMonth(currentValue ?? new Date());\n }\n setIsOpen(open);\n };\n\n const displayValue = hasFocus ? inputValue : formatDate(currentValue, '');\n\n return (\n <InputGroup state={state} focusVariant={focusVariant} className={className}>\n <InputGroup.Input\n {...restInputProps}\n ref={mergeRefs(ref ?? null, inputRef)}\n type=\"text\"\n value={displayValue}\n placeholder={placeholder}\n onChange={handleChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n disabled={disabled}\n readOnly={readOnly}\n />\n\n {(canClear || showPicker) && (\n <InputGroup.Addon align=\"inline-end\">\n {canClear && (\n <InputGroup.Button\n aria-label=\"Clear date\"\n onMouseDown={(event) => event.preventDefault()}\n onClick={handleClear}\n >\n <X className=\"tw:size-4\" />\n </InputGroup.Button>\n )}\n {showPicker && (\n <DatePicker\n disabled={disabledDays}\n endMonth={endMonth}\n mode=\"single\"\n month={month}\n onMonthChange={setMonth}\n onOpenChange={handleOpenChange}\n onSelect={handleDatePickerChange}\n open={isOpen}\n selected={currentValue ?? undefined}\n startMonth={startMonth}\n >\n <InputGroup.Button aria-label=\"Select Date\">\n <CalendarIcon className=\"tw:size-4\" />\n </InputGroup.Button>\n </DatePicker>\n )}\n </InputGroup.Addon>\n )}\n </InputGroup>\n );\n};\n"],"mappings":"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"}