@ngrok/mantle 0.66.17 → 0.68.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 (165) hide show
  1. package/README.md +32 -0
  2. package/dist/accordion.d.ts +9 -9
  3. package/dist/alert-dialog.d.ts +30 -30
  4. package/dist/alert-dialog.js +1 -1
  5. package/dist/alert.d.ts +12 -12
  6. package/dist/alert.js +1 -1
  7. package/dist/alert.js.map +1 -1
  8. package/dist/anchor.d.ts +3 -3
  9. package/dist/{as-child-XMVTepJu.d.ts → as-child-CRRsxi3Y.d.ts} +1 -1
  10. package/dist/badge.d.ts +4 -4
  11. package/dist/badge.js +1 -1
  12. package/dist/badge.js.map +1 -1
  13. package/dist/booleanish-CBGdPL3Q.js.map +1 -1
  14. package/dist/button-BKykcpgJ.js +2 -0
  15. package/dist/button-BKykcpgJ.js.map +1 -0
  16. package/dist/{button-ByK1wG1b.d.ts → button-BaNwe1ud.d.ts} +12 -12
  17. package/dist/button.d.ts +3 -3
  18. package/dist/button.js +1 -1
  19. package/dist/calendar.d.ts +2 -2
  20. package/dist/calendar.js +1 -1
  21. package/dist/card.d.ts +7 -7
  22. package/dist/checkbox.d.ts +4 -4
  23. package/dist/checkbox.js +1 -1
  24. package/dist/checkbox.js.map +1 -1
  25. package/dist/code-block.d.ts +187 -260
  26. package/dist/code-block.js +2 -8
  27. package/dist/code-block.js.map +1 -1
  28. package/dist/code-block_highlight-utils.d.ts +2 -0
  29. package/dist/code-block_highlight-utils.js +1 -0
  30. package/dist/code.d.ts +2 -2
  31. package/dist/code.js +1 -1
  32. package/dist/code.js.map +1 -1
  33. package/dist/color.d.ts +1 -1
  34. package/dist/color.js +1 -1
  35. package/dist/color.js.map +1 -1
  36. package/dist/combobox.d.ts +13 -13
  37. package/dist/combobox.js +1 -1
  38. package/dist/combobox.js.map +1 -1
  39. package/dist/command.d.ts +33 -33
  40. package/dist/command.js +1 -1
  41. package/dist/command.js.map +1 -1
  42. package/dist/data-table.d.ts +14 -14
  43. package/dist/data-table.js +1 -1
  44. package/dist/data-table.js.map +1 -1
  45. package/dist/{deep-non-nullable-BLM3Gz0I.d.ts → deep-non-nullable-BBByg3-i.d.ts} +1 -1
  46. package/dist/description-list.d.ts +6 -6
  47. package/dist/description-list.js +1 -1
  48. package/dist/description-list.js.map +1 -1
  49. package/dist/{dialog-DUOIIhuN.js → dialog-DxkpMIzB.js} +2 -2
  50. package/dist/{dialog-DUOIIhuN.js.map → dialog-DxkpMIzB.js.map} +1 -1
  51. package/dist/dialog.d.ts +17 -17
  52. package/dist/dialog.js +1 -1
  53. package/dist/{direction-DfrtFTny.js → direction-Ca88oQhP.js} +1 -1
  54. package/dist/{direction-DfrtFTny.js.map → direction-Ca88oQhP.js.map} +1 -1
  55. package/dist/{direction-DYYpi-JC.d.ts → direction-MVSxfKWx.d.ts} +2 -2
  56. package/dist/{dropdown-menu-CUwyTKyu.js → dropdown-menu-9nO7ch0t.js} +2 -2
  57. package/dist/{dropdown-menu-CUwyTKyu.js.map → dropdown-menu-9nO7ch0t.js.map} +1 -1
  58. package/dist/{dropdown-menu-BEjpuGrT.d.ts → dropdown-menu-D6MiVSR-.d.ts} +24 -24
  59. package/dist/dropdown-menu.d.ts +1 -1
  60. package/dist/dropdown-menu.js +1 -1
  61. package/dist/flag.d.ts +2 -2
  62. package/dist/hooks.d.ts +8 -4
  63. package/dist/hooks.js +1 -1
  64. package/dist/hover-card.d.ts +6 -6
  65. package/dist/{icon-B1XLv02t.d.ts → icon-Dh1ONyO_.d.ts} +4 -4
  66. package/dist/icon-button-CxxVPiKp.js +2 -0
  67. package/dist/icon-button-CxxVPiKp.js.map +1 -0
  68. package/dist/{icon-button-2r6S3HVA.d.ts → icon-button-gO-7F_MZ.d.ts} +8 -8
  69. package/dist/icon.d.ts +3 -3
  70. package/dist/icons.d.ts +10 -10
  71. package/dist/icons.js +1 -1
  72. package/dist/{in-view-ca-moloX.d.ts → in-view-DS0PgFGa.d.ts} +1 -1
  73. package/dist/{in-view-bPnaWEL4.js → in-view-DiFJ28EF.js} +1 -1
  74. package/dist/{in-view-bPnaWEL4.js.map → in-view-DiFJ28EF.js.map} +1 -1
  75. package/dist/{index-s8rMcilU.d.ts → index-BerTFFEC.d.ts} +1 -1
  76. package/dist/{index-DWqhfw9n.d.ts → index-Bw97R9Kw.d.ts} +9 -9
  77. package/dist/{index-BLCvtjLi.d.ts → index-C3IiAC5H.d.ts} +3 -3
  78. package/dist/{index-ViSCOUrU.d.ts → index-Cj2NX2Dg.d.ts} +6 -6
  79. package/dist/input.d.ts +2 -2
  80. package/dist/input.js +1 -1
  81. package/dist/{is-input-BFR8yMM7.js → is-input-CC_n6EGM.js} +1 -1
  82. package/dist/{is-input-BFR8yMM7.js.map → is-input-CC_n6EGM.js.map} +1 -1
  83. package/dist/{kbd-CtTyMWXB.js → kbd-wgm9K9D5.js} +1 -1
  84. package/dist/{kbd-CtTyMWXB.js.map → kbd-wgm9K9D5.js.map} +1 -1
  85. package/dist/kbd.d.ts +2 -2
  86. package/dist/kbd.js +1 -1
  87. package/dist/label.d.ts +3 -3
  88. package/dist/mantle-dark-high-contrast.css +18 -9
  89. package/dist/mantle-dark.css +37 -43
  90. package/dist/mantle-light-high-contrast.css +15 -9
  91. package/dist/mantle.css +154 -143
  92. package/dist/media-object.d.ts +5 -5
  93. package/dist/multi-select.d.ts +18 -18
  94. package/dist/multi-select.js +1 -1
  95. package/dist/multi-select.js.map +1 -1
  96. package/dist/pagination.d.ts +9 -9
  97. package/dist/pagination.js +1 -1
  98. package/dist/popover.d.ts +7 -7
  99. package/dist/{primitive-tuHqhoRE.d.ts → primitive-BqLYh79k.d.ts} +3 -3
  100. package/dist/progress.d.ts +5 -5
  101. package/dist/radio-group.d.ts +20 -20
  102. package/dist/radio-group.js +1 -1
  103. package/dist/radio-group.js.map +1 -1
  104. package/dist/resolve-pre-rendered-props-51i50IL2.d.ts +165 -0
  105. package/dist/resolve-pre-rendered-props-Bu2cvS9A.js +11 -0
  106. package/dist/resolve-pre-rendered-props-Bu2cvS9A.js.map +1 -0
  107. package/dist/sandboxed-on-click.d.ts +4 -4
  108. package/dist/{select-BkvbNKQ7.d.ts → select-DJmjfGjt.d.ts} +16 -16
  109. package/dist/{select-BXBu1jP_.js → select-Z13w6WBS.js} +2 -2
  110. package/dist/{select-BXBu1jP_.js.map → select-Z13w6WBS.js.map} +1 -1
  111. package/dist/select.d.ts +1 -1
  112. package/dist/select.js +1 -1
  113. package/dist/{separator-fSV4z0Pq.js → separator-BuP5aENE.js} +1 -1
  114. package/dist/{separator-fSV4z0Pq.js.map → separator-BuP5aENE.js.map} +1 -1
  115. package/dist/separator.d.ts +5 -5
  116. package/dist/separator.js +1 -1
  117. package/dist/sheet.d.ts +19 -19
  118. package/dist/sheet.js +1 -1
  119. package/dist/skeleton.d.ts +5 -5
  120. package/dist/slider.d.ts +2 -2
  121. package/dist/slider.js +1 -1
  122. package/dist/slider.js.map +1 -1
  123. package/dist/slot.d.ts +3 -3
  124. package/dist/{sort-CfPsu1Gs.js → sort-mo52clyh.js} +2 -2
  125. package/dist/{sort-CfPsu1Gs.js.map → sort-mo52clyh.js.map} +1 -1
  126. package/dist/split-button.d.ts +20 -20
  127. package/dist/split-button.js +1 -1
  128. package/dist/split-button.js.map +1 -1
  129. package/dist/{svg-only-Ct2mB46K.d.ts → svg-only-Db3eUPWM.d.ts} +4 -4
  130. package/dist/switch.d.ts +4 -4
  131. package/dist/switch.js +1 -1
  132. package/dist/switch.js.map +1 -1
  133. package/dist/{table-Bs1D5Aj7.d.ts → table-C7BejaFW.d.ts} +11 -11
  134. package/dist/table-CnYWz6IT.js +2 -0
  135. package/dist/table-CnYWz6IT.js.map +1 -0
  136. package/dist/table.d.ts +1 -1
  137. package/dist/table.js +1 -1
  138. package/dist/tabs.d.ts +9 -9
  139. package/dist/tabs.js +1 -1
  140. package/dist/tabs.js.map +1 -1
  141. package/dist/text-area.d.ts +3 -3
  142. package/dist/theme.d.ts +7 -7
  143. package/dist/{themes-Dk0VkyqX.d.ts → themes-D_v8H0nY.d.ts} +1 -1
  144. package/dist/toast.d.ts +10 -10
  145. package/dist/tooltip.d.ts +6 -6
  146. package/dist/{types-DgXUgkpc.d.ts → types-Cq6RWU7Q.d.ts} +1 -1
  147. package/dist/{types-Dh4BVhXC.d.ts → types-yU-Byhue.d.ts} +1 -1
  148. package/dist/types.d.ts +5 -5
  149. package/dist/use-copy-to-clipboard-B6wH6hDd.js +2 -0
  150. package/dist/use-copy-to-clipboard-B6wH6hDd.js.map +1 -0
  151. package/dist/{use-prefers-reduced-motion-BiG6QGkf.js → use-prefers-reduced-motion-BcwST13S.js} +1 -1
  152. package/dist/{use-prefers-reduced-motion-BiG6QGkf.js.map → use-prefers-reduced-motion-BcwST13S.js.map} +1 -1
  153. package/dist/utils.d.ts +2 -2
  154. package/dist/utils.js +1 -1
  155. package/dist/{variant-props-UE-phTwh.d.ts → variant-props-Bm6Y-jfm.d.ts} +2 -2
  156. package/dist/{with-style-props-D1QFTzj6.d.ts → with-style-props-9-k1s4ov.d.ts} +1 -1
  157. package/package.json +19 -16
  158. package/dist/button-CdPMhyKg.js +0 -2
  159. package/dist/button-CdPMhyKg.js.map +0 -1
  160. package/dist/icon-button-CeeHZOhh.js +0 -2
  161. package/dist/icon-button-CeeHZOhh.js.map +0 -1
  162. package/dist/table-bSFWy29w.js +0 -2
  163. package/dist/table-bSFWy29w.js.map +0 -1
  164. package/dist/use-copy-to-clipboard-BCpEp-sO.js +0 -2
  165. package/dist/use-copy-to-clipboard-BCpEp-sO.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"multi-select.js","names":[],"sources":["../src/components/multi-select/multi-select.tsx"],"sourcesContent":["\"use client\";\n\nimport * as Primitive from \"@ariakit/react\";\nimport { CheckIcon } from \"@phosphor-icons/react/Check\";\nimport { LockIcon } from \"@phosphor-icons/react/Lock\";\nimport { XIcon } from \"@phosphor-icons/react/X\";\nimport type {\n\tComponentProps,\n\tComponentPropsWithoutRef,\n\tComponentRef,\n\tKeyboardEvent,\n\tReactNode,\n\tRefObject,\n} from \"react\";\nimport {\n\tcreateContext,\n\tforwardRef,\n\tuseCallback,\n\tuseContext,\n\tuseEffect,\n\tuseMemo,\n\tuseRef,\n} from \"react\";\nimport type { WithAsChild } from \"../../types/as-child.js\";\nimport { getPrefersReducedMotion } from \"../../hooks/use-prefers-reduced-motion.js\";\nimport { composeRefs } from \"../../utils/compose-refs/compose-refs.js\";\nimport { cx } from \"../../utils/cx/cx.js\";\nimport { Icon } from \"../icon/icon.js\";\nimport type { WithValidation } from \"../input/types.js\";\nimport { Separator } from \"../separator/separator.js\";\nimport { Slot } from \"../slot/index.js\";\n\n/** Type guard to safely narrow Ariakit store state to `string[]` without `as` assertions. */\nconst isStringArray = (value: unknown): value is string[] =>\n\tArray.isArray(value) && value.every((item) => typeof item === \"string\");\n\n/** Stable empty array used as a fallback for `selectedValues` to avoid creating new arrays on every render. */\nconst EMPTY_ARRAY: string[] = [];\n\nconst TriggerRefContext = createContext<RefObject<HTMLDivElement | null>>({ current: null });\n\n/**\n * Shared ref for locked values. Written by `TagValues` during render so that `Item` can read\n * it synchronously and prevent deselection of locked values from the popover.\n * Using a ref (instead of state) avoids re-renders and keeps the write safe in render.\n */\nconst LockedValuesContext = createContext<{ current: string[] }>({ current: [] });\n\n/**\n * Bridges keyboard-nav state between `TagValues` and `Input`, which are siblings in the tree\n * and cannot communicate via a context that either one provides — it must come from a shared\n * ancestor (`Root`). Both refs are written by one side and read by the other:\n * - `onInputKeyDownRef`: written by `TagValues`, called by `Input` on keydown\n * - `inputRef`: written by `Input` (registers its DOM node), read by `TagValues` (to focus it)\n */\ntype TagBridgeContextValue = {\n\tonInputKeyDownRef: { current: ((event: KeyboardEvent<HTMLInputElement>) => void) | undefined };\n\tinputRef: { current: HTMLInputElement | null };\n};\n\nconst TagBridgeContext = createContext<TagBridgeContextValue>({\n\tonInputKeyDownRef: { current: undefined },\n\tinputRef: { current: null },\n});\n\ntype MultiSelectProps = Primitive.ComboboxProviderProps<string[]>;\n\n/**\n * Root component for a multi-select combobox. Provides state management for\n * selecting multiple values with typeahead filtering.\n *\n * @example\n * ```tsx\n * <MultiSelect.Root>\n * <MultiSelect.Trigger>\n * <MultiSelect.TagValues />\n * <MultiSelect.Input placeholder=\"Select items...\" />\n * </MultiSelect.Trigger>\n * <MultiSelect.Content>\n * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n * <MultiSelect.Item value=\"banana\">Banana</MultiSelect.Item>\n * </MultiSelect.Content>\n * </MultiSelect.Root>\n * ```\n */\nconst Root = ({ children, defaultSelectedValue = [], ...props }: MultiSelectProps) => {\n\tconst triggerRef = useRef<HTMLDivElement | null>(null);\n\tconst onInputKeyDownRef = useRef<((event: KeyboardEvent<HTMLInputElement>) => void) | undefined>(\n\t\tundefined,\n\t);\n\tconst inputRef = useRef<HTMLInputElement | null>(null);\n\tconst lockedValuesRef = useRef<string[]>([]);\n\tconst tagBridge = useMemo(() => ({ onInputKeyDownRef, inputRef }), []);\n\n\treturn (\n\t\t<TriggerRefContext.Provider value={triggerRef}>\n\t\t\t<TagBridgeContext.Provider value={tagBridge}>\n\t\t\t\t<LockedValuesContext.Provider value={lockedValuesRef}>\n\t\t\t\t\t<Primitive.ComboboxProvider<string[]>\n\t\t\t\t\t\tdefaultSelectedValue={defaultSelectedValue}\n\t\t\t\t\t\t{...props}\n\t\t\t\t\t>\n\t\t\t\t\t\t{children}\n\t\t\t\t\t</Primitive.ComboboxProvider>\n\t\t\t\t</LockedValuesContext.Provider>\n\t\t\t</TagBridgeContext.Provider>\n\t\t</TriggerRefContext.Provider>\n\t);\n};\nRoot.displayName = \"MultiSelect\";\n\ntype MultiSelectTriggerProps = ComponentPropsWithoutRef<\"div\"> & WithValidation;\n\n/**\n * The trigger container for the multi-select. Wraps the input and selected\n * value tags in a styled container that looks like a form input.\n *\n * @example\n * ```tsx\n * <MultiSelect.Root>\n * <MultiSelect.Trigger>\n * <MultiSelect.TagValues />\n * <MultiSelect.Input placeholder=\"Select items...\" />\n * </MultiSelect.Trigger>\n * <MultiSelect.Content>\n * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n * </MultiSelect.Content>\n * </MultiSelect.Root>\n * ```\n */\nconst Trigger = forwardRef<HTMLDivElement, MultiSelectTriggerProps>(\n\t(\n\t\t{\n\t\t\t\"aria-invalid\": _ariaInvalid,\n\t\t\tclassName,\n\t\t\tchildren,\n\t\t\tonKeyDown,\n\t\t\tonMouseDown,\n\t\t\tvalidation: _validation,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst triggerRef = useContext(TriggerRefContext);\n\t\tconst { inputRef } = useContext(TagBridgeContext);\n\t\tconst store = Primitive.useComboboxContext();\n\t\tconst isInvalid = _ariaInvalid != null && _ariaInvalid !== \"false\";\n\t\tconst validation = isInvalid\n\t\t\t? \"error\"\n\t\t\t: typeof _validation === \"function\"\n\t\t\t\t? _validation()\n\t\t\t\t: _validation;\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\trole=\"group\"\n\t\t\t\tdata-slot=\"multi-select-trigger\"\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"cursor-text select-none font-sans text-sm\",\n\t\t\t\t\t\"border-form bg-form text-strong flex w-full flex-wrap items-center gap-1 rounded-md border px-2 py-1.5\",\n\t\t\t\t\t\"has-focus:outline-hidden has-focus-within:ring-4 has-aria-expanded:ring-4\",\n\t\t\t\t\t\"has-focus-within:border-accent-600 has-focus-within:ring-focus-accent has-aria-expanded:border-accent-600 has-aria-expanded:ring-focus-accent\",\n\t\t\t\t\t\"hover:border-neutral-400\",\n\t\t\t\t\t\"data-validation-success:border-success-600 data-validation-success:has-focus-within:border-success-600 data-validation-success:has-focus-within:ring-focus-success data-validation-success:has-aria-expanded:border-success-600 data-validation-success:has-aria-expanded:ring-focus-success\",\n\t\t\t\t\t\"data-validation-warning:border-warning-600 data-validation-warning:has-focus-within:border-warning-600 data-validation-warning:has-focus-within:ring-focus-warning data-validation-warning:has-aria-expanded:border-warning-600 data-validation-warning:has-aria-expanded:ring-focus-warning\",\n\t\t\t\t\t\"data-validation-error:border-danger-600 data-validation-error:has-focus-within:border-danger-600 data-validation-error:has-focus-within:ring-focus-danger data-validation-error:has-aria-expanded:border-danger-600 data-validation-error:has-aria-expanded:ring-focus-danger\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tdata-validation={validation || undefined}\n\t\t\t\tonKeyDown={(event) => {\n\t\t\t\t\tif (event.key === \"Escape\" && store?.getState().open) {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\tstore.hide();\n\t\t\t\t\t}\n\t\t\t\t\tonKeyDown?.(event);\n\t\t\t\t}}\n\t\t\t\tonMouseDown={(event) => {\n\t\t\t\t\t// When clicking on non-interactive areas (padding, flex gaps between tags), prevent the\n\t\t\t\t\t// default mousedown behavior (which would cause text selection) and explicitly focus the\n\t\t\t\t\t// input. Clicks on buttons, the input itself, or tag spans are handled by those elements.\n\t\t\t\t\tif (\n\t\t\t\t\t\tevent.target instanceof HTMLElement &&\n\t\t\t\t\t\t!event.target.closest(\"button, input, [role='option']\")\n\t\t\t\t\t) {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\tinputRef.current?.focus();\n\t\t\t\t\t}\n\t\t\t\t\tonMouseDown?.(event);\n\t\t\t\t}}\n\t\t\t\tref={composeRefs(triggerRef, ref)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t);\n\t},\n);\nTrigger.displayName = \"MultiSelectTrigger\";\n\ntype TagProps = Omit<ComponentProps<\"span\">, \"children\"> & {\n\t/**\n\t * The value to display in the tag label.\n\t */\n\tvalue: string;\n\t/**\n\t * Called when the remove button is clicked.\n\t */\n\tonRemove?: () => void;\n\t/**\n\t * When true, the tag cannot be removed. The remove button is disabled and\n\t * Delete/Backspace key presses are ignored while the tag is focused.\n\t */\n\tlocked?: boolean;\n};\n\n/**\n * The default tag rendered inside `MultiSelect.TagValues` for each selected value.\n * Displays the value label with a remove button and full keyboard navigation support.\n *\n * Use this when building a custom `TagValues`-like component and you want the\n * default tag chrome with consistent styling.\n *\n * @example\n * ```tsx\n * <MultiSelect.Tag value=\"apple\" />\n * ```\n */\nconst Tag = forwardRef<HTMLSpanElement, TagProps>(\n\t({ className, value, onRemove, locked = false, onKeyDown, ...props }, ref) => {\n\t\tconst internalRef = useRef<HTMLSpanElement | null>(null);\n\n\t\treturn (\n\t\t\t<span\n\t\t\t\tref={composeRefs(internalRef, ref)}\n\t\t\t\trole=\"option\"\n\t\t\t\taria-selected\n\t\t\t\ttabIndex={-1}\n\t\t\t\tdata-slot=\"multi-select-tag\"\n\t\t\t\tdata-locked={locked || undefined}\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"cursor-default bg-neutral-100 border border-neutral-300 rounded-xs text-strong inline-flex items-center gap-1 pl-1.5 pr-1 py-0.5 text-xs font-semibold font-mono\",\n\t\t\t\t\t\"focus-visible:outline-hidden focus-visible:border-accent-600/50 focus-visible:ring-3 focus-visible:ring-focus-accent\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tonKeyDown={(event) => {\n\t\t\t\t\tif (locked && (event.key === \"Backspace\" || event.key === \"Delete\")) {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\tshakeElement(event.currentTarget);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tonKeyDown?.(event);\n\t\t\t\t}}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{value}\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\taria-label={`Remove ${value}`}\n\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\taria-disabled={locked || undefined}\n\t\t\t\t\tclassName={cx(\n\t\t\t\t\t\t\"cursor-pointer hover:bg-neutral-200 hover:text-strong text-strong/25 rounded-sm p-px size-4\",\n\t\t\t\t\t\t\"aria-disabled:cursor-default aria-disabled:hover:bg-transparent aria-disabled:hover:text-strong/25\",\n\t\t\t\t\t)}\n\t\t\t\t\tonClick={(event) => {\n\t\t\t\t\t\t// Prevent the click from bubbling to the trigger, which would reopen or refocus the combobox\n\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\tif (locked) {\n\t\t\t\t\t\t\t// Shake the tag to signal that removal is blocked\n\t\t\t\t\t\t\tconst tagElement = internalRef.current;\n\t\t\t\t\t\t\tif (tagElement) {\n\t\t\t\t\t\t\t\tshakeElement(tagElement);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tonRemove?.();\n\t\t\t\t\t}}\n\t\t\t\t\tonMouseDown={(event) => {\n\t\t\t\t\t\t// Prevent the input from losing focus on click, which would close the popover before the remove fires\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<Icon svg={locked ? <LockIcon /> : <XIcon weight=\"bold\" />} className=\"size-3\" />\n\t\t\t\t</button>\n\t\t\t</span>\n\t\t);\n\t},\n);\nTag.displayName = \"MultiSelectTag\";\n\n/**\n * Props passed to the children render function of `MultiSelect.TagValues`.\n * Spread these onto `MultiSelect.Tag` (or your own tag component) to\n * get the value, remove handler, locked state, and ref-based keyboard-nav\n * registration all wired up automatically.\n *\n * Pre-wired handlers included:\n * - `onKeyDown` — arrow-key nav between tags, Backspace/Delete to remove\n * - `onClick` — focuses the tag and ensures the popover opens/stays open\n */\ntype TagRenderProps = TagProps & {\n\t/** Ref callback — forward this to the tag element to enable keyboard navigation between tags. */\n\tref: (node: HTMLSpanElement | null) => void;\n};\n\ntype MultiSelectTagValuesProps = {\n\t/**\n\t * Values that cannot be removed. Locked tags have their remove button disabled,\n\t * respond to Backspace/Delete key presses with a shake animation, and shake when\n\t * Backspace is pressed on an empty input.\n\t *\n\t * The `locked` state is also forwarded to the render function via `props.locked`\n\t * so custom tag components receive it automatically.\n\t */\n\tlockedValues?: string[];\n\t/**\n\t * Optional render function for each tag. Receives `{ value, onRemove, locked, ref }` —\n\t * spread these onto `MultiSelect.Tag` (or your own element) for full keyboard-nav support.\n\t * When omitted, the default `MultiSelect.Tag` is rendered for each selected value.\n\t *\n\t * @example\n\t * ```tsx\n\t * <MultiSelect.TagValues lockedValues={[\"global\"]}>\n\t * {(props) => (\n\t * <MultiSelect.Tag key={props.value} {...props} />\n\t * )}\n\t * </MultiSelect.TagValues>\n\t * ```\n\t */\n\tchildren?: (props: TagRenderProps) => ReactNode;\n};\n\n/**\n * Renders the selected values as removable tags. Place this inside\n * `MultiSelect.Trigger`, followed by `MultiSelect.Input`.\n *\n * @example\n * ```tsx\n * <MultiSelect.Root>\n * <MultiSelect.Trigger>\n * <MultiSelect.TagValues />\n * <MultiSelect.Input placeholder=\"Select items...\" />\n * </MultiSelect.Trigger>\n * <MultiSelect.Content>\n * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n * </MultiSelect.Content>\n * </MultiSelect.Root>\n * ```\n */\nconst TagValues = ({ children, lockedValues = [] }: MultiSelectTagValuesProps) => {\n\tconst store = Primitive.useComboboxContext();\n\tconst rawSelectedValue = Primitive.useStoreState(store, \"selectedValue\");\n\tconst selectedValues = isStringArray(rawSelectedValue) ? rawSelectedValue : undefined;\n\tconst selectedArray = selectedValues ?? EMPTY_ARRAY;\n\t// Keep refs in sync so requestAnimationFrame callbacks always read fresh state\n\t// instead of closing over stale values from the render they were scheduled in.\n\tconst selectedArrayRef = useRef<string[]>(selectedArray);\n\tselectedArrayRef.current = selectedArray;\n\t// Use the shared LockedValuesContext ref so Item can also read locked values\n\t// without a separate prop. Writing a ref during render is safe here because\n\t// refs are mutable and don't trigger re-renders.\n\tconst lockedValuesRef = useContext(LockedValuesContext);\n\tlockedValuesRef.current = lockedValues;\n\tconst lockedValuesSet = useMemo(() => new Set(lockedValues), [lockedValues]);\n\tconst tagRefs = useRef<Map<string, HTMLSpanElement>>(new Map());\n\tconst { onInputKeyDownRef, inputRef } = useContext(TagBridgeContext);\n\t// Track pending rAF IDs so we can cancel them on unmount and avoid calling\n\t// focus() on detached DOM nodes if the component unmounts mid-frame.\n\tconst pendingRafsRef = useRef<Set<number>>(new Set());\n\tuseEffect(\n\t\t() => () => {\n\t\t\tpendingRafsRef.current.forEach(cancelAnimationFrame);\n\t\t},\n\t\t[],\n\t);\n\tconst raf = (callback: () => void): void => {\n\t\tlet id: number;\n\t\tid = requestAnimationFrame(() => {\n\t\t\t// Remove the id once the rAF has fired so the set doesn't grow unbounded.\n\t\t\tpendingRafsRef.current.delete(id);\n\t\t\tcallback();\n\t\t});\n\t\tpendingRafsRef.current.add(id);\n\t};\n\n\tconst removeValue = (value: string) => {\n\t\tif (store) {\n\t\t\tconst selected = store.getState().selectedValue;\n\t\t\tif (!isStringArray(selected)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tstore.setSelectedValue(selected.filter((v) => v !== value));\n\t\t}\n\t};\n\n\tconst focusTag = (index: number) => {\n\t\tconst value = selectedArrayRef.current[index];\n\t\tif (value == null) {\n\t\t\treturn;\n\t\t}\n\t\tconst tagElement = tagRefs.current.get(value);\n\t\tif (tagElement) {\n\t\t\ttagElement.focus();\n\t\t\t// Keep the popover open while a tag is focused. Ariakit closes the\n\t\t\t// popover when the combobox input loses focus, so we reopen it here.\n\t\t\tstore?.show();\n\t\t}\n\t};\n\n\tconst focusInput = () => {\n\t\tinputRef.current?.focus();\n\t};\n\n\tconst handleTagKeyDown = (event: KeyboardEvent<HTMLSpanElement>, index: number) => {\n\t\tconst value = selectedArray[index];\n\t\tswitch (event.key) {\n\t\t\tcase \"ArrowLeft\": {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tif (index > 0) {\n\t\t\t\t\tfocusTag(index - 1);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"ArrowRight\": {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tif (index < selectedArray.length - 1) {\n\t\t\t\t\tfocusTag(index + 1);\n\t\t\t\t} else {\n\t\t\t\t\tfocusInput();\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"Backspace\":\n\t\t\tcase \"Delete\": {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tif (value != null) {\n\t\t\t\t\t// Respect locked values: shake instead of removing when locked.\n\t\t\t\t\tif (lockedValuesSet.has(value)) {\n\t\t\t\t\t\tconst tagElement = tagRefs.current.get(value);\n\t\t\t\t\t\tif (tagElement) {\n\t\t\t\t\t\t\tshakeElement(tagElement);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tremoveValue(value);\n\t\t\t\t\t// After removal, the array shifts. Focus the next logical tag or the input.\n\t\t\t\t\tif (event.key === \"Backspace\") {\n\t\t\t\t\t\tif (index > 0) {\n\t\t\t\t\t\t\t// Focus the previous tag (will have same index - 1 after removal)\n\t\t\t\t\t\t\t// We need to wait for the next render, so use requestAnimationFrame\n\t\t\t\t\t\t\tconst prevIndex = index - 1;\n\t\t\t\t\t\t\traf(() => focusTag(prevIndex));\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\traf(() => {\n\t\t\t\t\t\t\t\tif (selectedArrayRef.current.length > 0) {\n\t\t\t\t\t\t\t\t\tfocusTag(0);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tfocusInput();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Delete: move focus right\n\t\t\t\t\t\traf(() => {\n\t\t\t\t\t\t\t// index stays the same since the item at `index` was removed and the next one slides in\n\t\t\t\t\t\t\tif (index < selectedArrayRef.current.length) {\n\t\t\t\t\t\t\t\tfocusTag(index);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tfocusInput();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"ArrowUp\":\n\t\t\tcase \"ArrowDown\": {\n\t\t\t\t// Don't scroll the page. Instead, focus the input and forward the key\n\t\t\t\t// to Ariakit so it navigates the popover list.\n\t\t\t\tevent.preventDefault();\n\t\t\t\tfocusInput();\n\t\t\t\tinputRef.current?.dispatchEvent(\n\t\t\t\t\tnew KeyboardEvent(\"keydown\", {\n\t\t\t\t\t\tkey: event.key,\n\t\t\t\t\t\tbubbles: true,\n\t\t\t\t\t\tcancelable: true,\n\t\t\t\t\t\tshiftKey: event.shiftKey,\n\t\t\t\t\t\tctrlKey: event.ctrlKey,\n\t\t\t\t\t\tmetaKey: event.metaKey,\n\t\t\t\t\t\taltKey: event.altKey,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\t// If a printable character is typed while a tag is focused, jump to input\n\t\t\t\tif (event.key.length === 1 && !event.ctrlKey && !event.metaKey) {\n\t\t\t\t\tfocusInput();\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t};\n\n\tconst handleInputKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n\t\tif (\n\t\t\tevent.key === \"ArrowLeft\" &&\n\t\t\tevent.currentTarget.selectionStart === 0 &&\n\t\t\tevent.currentTarget.selectionEnd === 0 &&\n\t\t\tselectedArray.length > 0\n\t\t) {\n\t\t\tevent.preventDefault();\n\t\t\tfocusTag(selectedArray.length - 1);\n\t\t\treturn;\n\t\t}\n\t\tif (event.key === \"Backspace\" && event.currentTarget.value === \"\" && selectedArray.length > 0) {\n\t\t\tconst lastValue = selectedArray[selectedArray.length - 1];\n\t\t\tif (lastValue != null) {\n\t\t\t\tif (lockedValuesRef.current.includes(lastValue)) {\n\t\t\t\t\t// The last tag is locked — shake it to signal that removal is blocked.\n\t\t\t\t\tconst tagElement = tagRefs.current.get(lastValue);\n\t\t\t\t\tif (tagElement) {\n\t\t\t\t\t\tshakeElement(tagElement);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tremoveValue(lastValue);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t// Write the latest handler into the bridge ref so Input can call it via onKeyDown.\n\t// Assigned directly during render (safe — refs are mutable and don't trigger re-renders).\n\tonInputKeyDownRef.current = handleInputKeyDown;\n\n\treturn (\n\t\t<>\n\t\t\t{selectedArray.map((value, index) => {\n\t\t\t\tconst tagOptionProps: TagRenderProps = {\n\t\t\t\t\tvalue,\n\t\t\t\t\tlocked: lockedValuesSet.has(value),\n\t\t\t\t\tonRemove: () => {\n\t\t\t\t\t\t// Respect locked values: shake instead of removing when locked.\n\t\t\t\t\t\t// This guards custom tag renderers that call onRemove directly.\n\t\t\t\t\t\tif (lockedValuesSet.has(value)) {\n\t\t\t\t\t\t\tconst tagElement = tagRefs.current.get(value);\n\t\t\t\t\t\t\tif (tagElement) {\n\t\t\t\t\t\t\t\tshakeElement(tagElement);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tremoveValue(value);\n\t\t\t\t\t},\n\t\t\t\t\tref: (node: HTMLSpanElement | null) => {\n\t\t\t\t\t\tif (node) {\n\t\t\t\t\t\t\ttagRefs.current.set(value, node);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttagRefs.current.delete(value);\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tonKeyDown: (event: KeyboardEvent<HTMLSpanElement>) => handleTagKeyDown(event, index),\n\t\t\t\t\t// Ensure the popover opens/stays open when a tag is clicked,\n\t\t\t\t\t// including when the component was fully blurred before the click.\n\t\t\t\t\tonClick: () => focusTag(index),\n\t\t\t\t};\n\n\t\t\t\tif (children) {\n\t\t\t\t\treturn children(tagOptionProps);\n\t\t\t\t}\n\n\t\t\t\treturn <Tag key={value} {...tagOptionProps} />;\n\t\t\t})}\n\t\t</>\n\t);\n};\nTagValues.displayName = \"MultiSelectTagValues\";\n\ntype MultiSelectInputProps = Omit<Primitive.ComboboxProps, \"render\"> & {\n\t/**\n\t * Called with the raw string value whenever the input text changes.\n\t * Use this to drive external filtering (e.g. with matchSorter) without\n\t * having to unwrap the DOM event. A convenience alternative to `onChange`.\n\t */\n\tonValueChange?: (value: string) => void;\n};\n\n/**\n * The combobox input for filtering items. Place this inside `MultiSelect.Trigger`,\n * after `MultiSelect.TagValues`.\n *\n * @example\n * ```tsx\n * <MultiSelect.Root>\n * <MultiSelect.Trigger>\n * <MultiSelect.TagValues />\n * <MultiSelect.Input placeholder=\"Select items...\" />\n * </MultiSelect.Trigger>\n * <MultiSelect.Content>\n * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n * </MultiSelect.Content>\n * </MultiSelect.Root>\n * ```\n */\nconst Input = forwardRef<ComponentRef<\"input\">, MultiSelectInputProps>(\n\t(\n\t\t{ className, onBlur, onChange, onFocus, onKeyDown, onValueChange, placeholder, ...props },\n\t\tref,\n\t) => {\n\t\tconst store = Primitive.useComboboxContext();\n\t\tconst { onInputKeyDownRef, inputRef } = useContext(TagBridgeContext);\n\t\tconst rawSelectedValue = Primitive.useStoreState(store, \"selectedValue\");\n\t\tconst selectedValues = isStringArray(rawSelectedValue) ? rawSelectedValue : undefined;\n\t\tconst hasSelectedValues = (selectedValues?.length ?? 0) > 0;\n\n\t\treturn (\n\t\t\t<Primitive.Combobox\n\t\t\t\tautoSelect\n\t\t\t\tdata-slot=\"multi-select-input\"\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"pointer-coarse:text-base min-w-20 flex-1 select-text border-0 bg-transparent text-sm outline-hidden\",\n\t\t\t\t\t\"placeholder:select-none placeholder:text-placeholder\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tonChange={(event) => {\n\t\t\t\t\tonValueChange?.(event.target.value);\n\t\t\t\t\tonChange?.(event);\n\t\t\t\t}}\n\t\t\t\tonKeyDown={(event) => {\n\t\t\t\t\tonInputKeyDownRef.current?.(event);\n\t\t\t\t\tonKeyDown?.(event);\n\t\t\t\t}}\n\t\t\t\tonBlur={(event) => {\n\t\t\t\t\t// When focus moves from the input to a tag, Ariakit would normally\n\t\t\t\t\t// close the popover because the combobox input lost focus. Keep it\n\t\t\t\t\t// open so the user can see the list while navigating tags.\n\t\t\t\t\tif (\n\t\t\t\t\t\tevent.relatedTarget instanceof HTMLElement &&\n\t\t\t\t\t\tevent.relatedTarget.closest('[data-slot=\"multi-select-tag\"]')\n\t\t\t\t\t) {\n\t\t\t\t\t\tstore?.show();\n\t\t\t\t\t}\n\t\t\t\t\tonBlur?.(event);\n\t\t\t\t}}\n\t\t\t\tonFocus={(event) => {\n\t\t\t\t\t// Ariakit doesn't always open the popover on focus when the input is\n\t\t\t\t\t// already mounted (e.g. returning focus from a tag). Force it open.\n\t\t\t\t\tstore?.show();\n\t\t\t\t\tonFocus?.(event);\n\t\t\t\t}}\n\t\t\t\tplaceholder={hasSelectedValues ? undefined : placeholder}\n\t\t\t\t// Register the input's DOM node in the bridge so TagValues can focus it for keyboard nav.\n\t\t\t\tref={composeRefs(inputRef, ref)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t);\n\t},\n);\nInput.displayName = \"MultiSelectInput\";\n\ntype MultiSelectContentProps = Omit<Primitive.ComboboxPopoverProps, \"render\"> & WithAsChild;\n\n/**\n * Renders a popover that contains multi-select content, such as items, groups,\n * and separators. Opens below the trigger.\n *\n * @example\n * ```tsx\n * <MultiSelect.Root>\n * <MultiSelect.Trigger>\n * <MultiSelect.TagValues />\n * <MultiSelect.Input placeholder=\"Select items...\" />\n * </MultiSelect.Trigger>\n * <MultiSelect.Content>\n * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n * <MultiSelect.Item value=\"banana\">Banana</MultiSelect.Item>\n * </MultiSelect.Content>\n * </MultiSelect.Root>\n * ```\n */\nconst Content = forwardRef<ComponentRef<\"div\">, MultiSelectContentProps>(\n\t(\n\t\t{\n\t\t\tasChild = false,\n\t\t\tbackdrop = false,\n\t\t\tchildren,\n\t\t\tclassName,\n\t\t\tmodal = true,\n\t\t\tportalElement,\n\t\t\tsameWidth = true,\n\t\t\tunmountOnHide = true,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst triggerRef = useContext(TriggerRefContext);\n\n\t\tconst getAnchorRect = useCallback(() => {\n\t\t\treturn triggerRef.current?.getBoundingClientRect() ?? null;\n\t\t}, [triggerRef]);\n\n\t\tconst getPortalElement = useCallback(\n\t\t\t(element: HTMLElement) => {\n\t\t\t\tif (typeof portalElement === \"function\") {\n\t\t\t\t\treturn portalElement(element);\n\t\t\t\t}\n\n\t\t\t\treturn (\n\t\t\t\t\tportalElement ??\n\t\t\t\t\ttriggerRef.current?.closest<HTMLElement>(\"[data-mantle-modal-content]\") ??\n\t\t\t\t\telement.ownerDocument.body\n\t\t\t\t);\n\t\t\t},\n\t\t\t[portalElement, triggerRef],\n\t\t);\n\n\t\tconst hideOnInteractOutside = useCallback(\n\t\t\t(event: Event) => {\n\t\t\t\t// Keep the popover open when interacting with any part of the trigger\n\t\t\t\t// (tags, buttons, input, padding). Ariakit would otherwise close on any\n\t\t\t\t// mousedown outside the popover — including tag clicks.\n\t\t\t\tif (event.target instanceof Node && triggerRef.current?.contains(event.target)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t},\n\t\t\t[triggerRef],\n\t\t);\n\n\t\treturn (\n\t\t\t<Primitive.ComboboxPopover\n\t\t\t\tdata-slot=\"multi-select-content\"\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"border-popover bg-popover relative z-50 max-h-96 min-w-32 scrollbar overflow-y-scroll overflow-x-hidden overscroll-y-none rounded-md border shadow-md pt-1 pb-1 has-data-content-footer:pb-0 font-sans flex flex-col gap-px focus:outline-hidden\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tbackdrop={backdrop}\n\t\t\t\tgetAnchorRect={getAnchorRect}\n\t\t\t\tgutter={4}\n\t\t\t\thideOnInteractOutside={hideOnInteractOutside}\n\t\t\t\tmodal={modal}\n\t\t\t\tportalElement={getPortalElement}\n\t\t\t\tref={ref}\n\t\t\t\trender={\n\t\t\t\t\tasChild ? ({ ref, ...childProps }) => <Slot ref={ref} {...childProps} /> : undefined\n\t\t\t\t}\n\t\t\t\tsameWidth={sameWidth}\n\t\t\t\tunmountOnHide={unmountOnHide}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</Primitive.ComboboxPopover>\n\t\t);\n\t},\n);\nContent.displayName = \"MultiSelectContent\";\n\ntype MultiSelectItemProps = Omit<Primitive.ComboboxItemProps, \"render\"> & WithAsChild;\n\n/**\n * Renders a selectable item inside a `MultiSelect.Content` component.\n * Items display a checkbox indicator when selected.\n *\n * @example\n * ```tsx\n * <MultiSelect.Content>\n * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n * <MultiSelect.Item value=\"banana\">Banana</MultiSelect.Item>\n * </MultiSelect.Content>\n * ```\n */\nconst Item = forwardRef<ComponentRef<\"div\">, MultiSelectItemProps>(\n\t(\n\t\t{ asChild = false, children, className, focusOnHover = true, value, onClick, ...props },\n\t\tref,\n\t) => {\n\t\tconst lockedValuesRef = useContext(LockedValuesContext);\n\t\tconst isLocked = value != null && lockedValuesRef.current.includes(value);\n\n\t\treturn (\n\t\t\t<Primitive.ComboboxItem\n\t\t\t\tdata-slot=\"multi-select-item\"\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"mx-1 cursor-pointer rounded-md px-2 py-1.5 text-strong text-sm font-normal flex min-w-0 items-center justify-between gap-2\",\n\t\t\t\t\t\"[[role=option]+&]:mt-px\",\n\t\t\t\t\t\"data-active-item:bg-active-menu-item\",\n\t\t\t\t\t\"aria-disabled:opacity-50\",\n\t\t\t\t\t\"aria-selected:bg-selected-menu-item aria-selected:data-active-item:bg-active-selected-menu-item\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tfocusOnHover={focusOnHover}\n\t\t\t\tonClick={(event) => {\n\t\t\t\t\t// Prevent Ariakit from toggling off a locked value.\n\t\t\t\t\t// Ariakit checks event.defaultPrevented before executing its selection logic.\n\t\t\t\t\tif (isLocked) {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tonClick?.(event);\n\t\t\t\t}}\n\t\t\t\tref={ref}\n\t\t\t\trender={\n\t\t\t\t\tasChild ? ({ ref, ...childProps }) => <Slot ref={ref} {...childProps} /> : undefined\n\t\t\t\t}\n\t\t\t\tresetValueOnSelect\n\t\t\t\tvalue={value}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t\t<Primitive.ComboboxItemCheck>\n\t\t\t\t\t<Icon svg={<CheckIcon weight=\"bold\" />} className=\"size-4 text-accent-600\" />\n\t\t\t\t</Primitive.ComboboxItemCheck>\n\t\t\t</Primitive.ComboboxItem>\n\t\t);\n\t},\n);\nItem.displayName = \"MultiSelectItem\";\n\ntype MultiSelectGroupProps = Omit<Primitive.ComboboxGroupProps, \"render\"> & WithAsChild;\n\n/**\n * Renders a group for MultiSelect.Item elements.\n *\n * @example\n * ```tsx\n * <MultiSelect.Content>\n * <MultiSelect.Group>\n * <MultiSelect.GroupLabel>Fruits</MultiSelect.GroupLabel>\n * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n * <MultiSelect.Item value=\"banana\">Banana</MultiSelect.Item>\n * </MultiSelect.Group>\n * </MultiSelect.Content>\n * ```\n */\nconst Group = forwardRef<ComponentRef<\"div\">, MultiSelectGroupProps>(\n\t({ asChild = false, children, ...props }, ref) => {\n\t\treturn (\n\t\t\t<Primitive.ComboboxGroup\n\t\t\t\tdata-slot=\"multi-select-group\"\n\t\t\t\tclassName=\"mx-1\"\n\t\t\t\tref={ref}\n\t\t\t\trender={\n\t\t\t\t\tasChild ? ({ ref, ...childProps }) => <Slot ref={ref} {...childProps} /> : undefined\n\t\t\t\t}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</Primitive.ComboboxGroup>\n\t\t);\n\t},\n);\nGroup.displayName = \"MultiSelectGroup\";\n\ntype MultiSelectGroupLabelProps = Omit<Primitive.ComboboxGroupLabelProps, \"render\"> & WithAsChild;\n\n/**\n * Renders a label in a multi-select group.\n *\n * @example\n * ```tsx\n * <MultiSelect.Content>\n * <MultiSelect.Group>\n * <MultiSelect.GroupLabel>Fruits</MultiSelect.GroupLabel>\n * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n * </MultiSelect.Group>\n * </MultiSelect.Content>\n * ```\n */\nconst GroupLabel = forwardRef<ComponentRef<\"div\">, MultiSelectGroupLabelProps>(\n\t({ asChild = false, children, className, ...props }, ref) => {\n\t\treturn (\n\t\t\t<Primitive.ComboboxGroupLabel\n\t\t\t\tdata-slot=\"multi-select-group-label\"\n\t\t\t\tclassName={cx(\"text-muted px-2 py-1 text-xs font-medium\", className)}\n\t\t\t\tref={ref}\n\t\t\t\trender={\n\t\t\t\t\tasChild ? ({ ref, ...childProps }) => <Slot ref={ref} {...childProps} /> : undefined\n\t\t\t\t}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</Primitive.ComboboxGroupLabel>\n\t\t);\n\t},\n);\nGroupLabel.displayName = \"MultiSelectGroupLabel\";\n\ntype MultiSelectGroupDescriptionProps = ComponentPropsWithoutRef<\"p\">;\n\n/**\n * Renders a description below a `MultiSelect.GroupLabel` inside a `MultiSelect.Group`.\n * Provides context about the group's purpose or constraints.\n *\n * @example\n * ```tsx\n * <MultiSelect.Group>\n * <MultiSelect.GroupLabel>Regional Aliases</MultiSelect.GroupLabel>\n * <MultiSelect.GroupDescription>\n * Include all points of presence that are geographically within the region.\n * </MultiSelect.GroupDescription>\n * <MultiSelect.Item value=\"global\">global</MultiSelect.Item>\n * </MultiSelect.Group>\n * ```\n */\nconst GroupDescription = forwardRef<HTMLParagraphElement, MultiSelectGroupDescriptionProps>(\n\t({ className, children, ...props }, ref) => {\n\t\treturn (\n\t\t\t<p\n\t\t\t\tdata-slot=\"multi-select-group-description\"\n\t\t\t\tclassName={cx(\"text-muted px-2 pb-1 text-xs\", className)}\n\t\t\t\tref={ref}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</p>\n\t\t);\n\t},\n);\nGroupDescription.displayName = \"MultiSelectGroupDescription\";\n\n/**\n * Renders a separator between MultiSelect.Items or MultiSelect.Groups.\n *\n * @example\n * ```tsx\n * <MultiSelect.Content>\n * <MultiSelect.Group>\n * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n * </MultiSelect.Group>\n * <MultiSelect.Separator />\n * <MultiSelect.Group>\n * <MultiSelect.Item value=\"carrot\">Carrot</MultiSelect.Item>\n * </MultiSelect.Group>\n * </MultiSelect.Content>\n * ```\n */\nconst MultiSelectSeparatorComponent = forwardRef<\n\tComponentRef<\"div\">,\n\tComponentPropsWithoutRef<typeof Separator>\n>(({ className, ...props }, ref) => (\n\t<Separator\n\t\tdata-slot=\"multi-select-separator\"\n\t\tref={ref}\n\t\tclassName={cx(\"my-1 w-auto\", className)}\n\t\t{...props}\n\t/>\n));\nMultiSelectSeparatorComponent.displayName = \"MultiSelectSeparator\";\n\ntype MultiSelectEmptyProps = ComponentPropsWithoutRef<\"div\">;\n\n/**\n * Renders a message when no items match the current filter.\n *\n * @example\n * ```tsx\n * <MultiSelect.Content>\n * {matches.length === 0 && (\n * <MultiSelect.Empty>No results found</MultiSelect.Empty>\n * )}\n * </MultiSelect.Content>\n * ```\n */\nconst Empty = forwardRef<HTMLDivElement, MultiSelectEmptyProps>(\n\t({ className, children, ...props }, ref) => {\n\t\treturn (\n\t\t\t<div\n\t\t\t\tdata-slot=\"multi-select-empty\"\n\t\t\t\tclassName={cx(\"mx-1 text-muted px-2 py-6 text-center text-sm\", className)}\n\t\t\t\tref={ref}\n\t\t\t\trole=\"presentation\"\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t);\n\t},\n);\nEmpty.displayName = \"MultiSelectEmpty\";\n\ntype MultiSelectContentFooterProps = ComponentPropsWithoutRef<\"div\">;\n\n/**\n * Renders a sticky footer pinned to the bottom inside `MultiSelect.Content`,\n * with a separator border at the top.\n *\n * @example\n * ```tsx\n * <MultiSelect.Content>\n * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n * <MultiSelect.ContentFooter>\n * <p>Upgrade to unlock more options.</p>\n * <Button>Upgrade</Button>\n * </MultiSelect.ContentFooter>\n * </MultiSelect.Content>\n * ```\n */\nconst ContentFooter = forwardRef<HTMLDivElement, MultiSelectContentFooterProps>(\n\t({ className, children, ...props }, ref) => {\n\t\treturn (\n\t\t\t<div\n\t\t\t\tref={ref}\n\t\t\t\tdata-slot=\"multi-select-content-footer\"\n\t\t\t\tdata-content-footer\n\t\t\t\tclassName={cx(\"bg-popover sticky bottom-0 border-t border-popover\", className)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t);\n\t},\n);\nContentFooter.displayName = \"MultiSelectContentFooter\";\n\n/**\n * A multi-select combobox that allows users to select multiple values with\n * typeahead filtering. Selected values are displayed as removable tags.\n *\n * Built on top of Ariakit's Combobox primitives with full keyboard support\n * and WAI-ARIA compliance.\n *\n * @see https://www.w3.org/WAI/ARIA/apg/patterns/combobox/\n * @see https://ariakit.org/components/combobox\n *\n * @example\n * ```tsx\n * <MultiSelect.Root>\n * <MultiSelect.Trigger>\n * <MultiSelect.TagValues />\n * <MultiSelect.Input placeholder=\"Select items...\" />\n * </MultiSelect.Trigger>\n * <MultiSelect.Content>\n * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n * <MultiSelect.Item value=\"banana\">Banana</MultiSelect.Item>\n * <MultiSelect.Item value=\"cherry\">Cherry</MultiSelect.Item>\n * </MultiSelect.Content>\n * </MultiSelect.Root>\n * ```\n */\nconst MultiSelect = {\n\t/**\n\t * Root component for a multi-select combobox. Provides state management for\n\t * selecting multiple values with typeahead filtering.\n\t *\n\t * @example\n\t * ```tsx\n\t * <MultiSelect.Root>\n\t * <MultiSelect.Trigger>\n\t * <MultiSelect.TagValues />\n\t * <MultiSelect.Input placeholder=\"Select items...\" />\n\t * </MultiSelect.Trigger>\n\t * <MultiSelect.Content>\n\t * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n\t * </MultiSelect.Content>\n\t * </MultiSelect.Root>\n\t * ```\n\t */\n\tRoot,\n\t/**\n\t * The trigger container for the multi-select. Wraps the tags and input\n\t * in a styled container.\n\t *\n\t * @example\n\t * ```tsx\n\t * <MultiSelect.Trigger>\n\t * <MultiSelect.TagValues />\n\t * <MultiSelect.Input placeholder=\"Select items...\" />\n\t * </MultiSelect.Trigger>\n\t * ```\n\t */\n\tTrigger,\n\t/**\n\t * Renders the selected values as removable tags. Place this inside\n\t * `MultiSelect.Trigger`, followed by `MultiSelect.Input`.\n\t *\n\t * Use `lockedValues` to prevent specific tags from being removed. Locked tags\n\t * have their remove button disabled and shake when Backspace is pressed.\n\t *\n\t * @example\n\t * ```tsx\n\t * // Default tags with locking\n\t * <MultiSelect.TagValues lockedValues={[\"global\"]} />\n\t *\n\t * // Custom tags via children render function — locked is forwarded via props\n\t * <MultiSelect.TagValues lockedValues={[\"global\"]}>\n\t * {(props) => (\n\t * <MultiSelect.Tag key={props.value} {...props} />\n\t * )}\n\t * </MultiSelect.TagValues>\n\t * ```\n\t */\n\tTagValues,\n\t/**\n\t * The combobox input for filtering items. Place this inside\n\t * `MultiSelect.Trigger`, after `MultiSelect.TagValues`.\n\t *\n\t * @example\n\t * ```tsx\n\t * <MultiSelect.Input placeholder=\"Select items...\" />\n\t * ```\n\t */\n\tInput,\n\t/**\n\t * The default tag rendered inside `MultiSelect.TagValues` for each selected value.\n\t * Displays the value label with a remove button and keyboard navigation support.\n\t *\n\t * @example\n\t * ```tsx\n\t * <MultiSelect.Tag\n\t * value=\"apple\"\n\t * onRemove={() => removeValue(\"apple\")}\n\t * />\n\t * ```\n\t */\n\tTag,\n\t/**\n\t * Renders a popover that contains multi-select content.\n\t *\n\t * @example\n\t * ```tsx\n\t * <MultiSelect.Content>\n\t * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n\t * </MultiSelect.Content>\n\t * ```\n\t */\n\tContent,\n\t/**\n\t * Renders a sticky footer pinned to the bottom inside `MultiSelect.Content`,\n\t * with a separator border at the top.\n\t *\n\t * @example\n\t * ```tsx\n\t * <MultiSelect.ContentFooter>\n\t * <p>Upgrade to unlock more options.</p>\n\t * </MultiSelect.ContentFooter>\n\t * ```\n\t */\n\tContentFooter,\n\t/**\n\t * Renders a selectable item with a checkbox indicator inside a `MultiSelect.Content`.\n\t *\n\t * @example\n\t * ```tsx\n\t * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n\t * ```\n\t */\n\tItem,\n\t/**\n\t * Renders a group for MultiSelect.Item elements.\n\t *\n\t * @example\n\t * ```tsx\n\t * <MultiSelect.Group>\n\t * <MultiSelect.GroupLabel>Fruits</MultiSelect.GroupLabel>\n\t * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n\t * </MultiSelect.Group>\n\t * ```\n\t */\n\tGroup,\n\t/**\n\t * Renders a label in a multi-select group.\n\t *\n\t * @example\n\t * ```tsx\n\t * <MultiSelect.GroupLabel>Fruits</MultiSelect.GroupLabel>\n\t * ```\n\t */\n\tGroupLabel,\n\t/**\n\t * Renders a description below a `MultiSelect.GroupLabel` inside a `MultiSelect.Group`.\n\t *\n\t * @example\n\t * ```tsx\n\t * <MultiSelect.GroupDescription>\n\t * Include all points of presence within the region.\n\t * </MultiSelect.GroupDescription>\n\t * ```\n\t */\n\tGroupDescription,\n\t/**\n\t * Renders a separator between items or groups.\n\t *\n\t * @example\n\t * ```tsx\n\t * <MultiSelect.Separator />\n\t * ```\n\t */\n\tSeparator: MultiSelectSeparatorComponent,\n\t/**\n\t * Renders a message when no items match the current filter.\n\t *\n\t * @example\n\t * ```tsx\n\t * <MultiSelect.Empty>No results found</MultiSelect.Empty>\n\t * ```\n\t */\n\tEmpty,\n} as const;\n\nexport {\n\t//,\n\tMultiSelect,\n};\n\n/**\n * Shakes an element left-right to signal that an action was blocked\n * (e.g. pressing Backspace/Delete on a locked tag). No-ops when the user\n * has enabled reduced motion in their OS/browser accessibility settings.\n */\nfunction shakeElement(element: HTMLElement): void {\n\t// Skip the animation when the user has opted into reduced motion.\n\t// Called from event handlers only, so reading the media query imperatively\n\t// is safe and gives the freshest value without any hook plumbing.\n\tif (getPrefersReducedMotion()) {\n\t\treturn;\n\t}\n\n\telement.animate(\n\t\t[\n\t\t\t{ transform: \"translateX(0)\" },\n\t\t\t{ transform: \"translateX(-4px)\" },\n\t\t\t{ transform: \"translateX(4px)\" },\n\t\t\t{ transform: \"translateX(-4px)\" },\n\t\t\t{ transform: \"translateX(4px)\" },\n\t\t\t{ transform: \"translateX(0)\" },\n\t\t],\n\t\t{ duration: 300, easing: \"ease-in-out\" },\n\t);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"multi-select.js","names":[],"sources":["../src/components/multi-select/multi-select.tsx"],"sourcesContent":["\"use client\";\n\nimport * as Primitive from \"@ariakit/react\";\nimport { CheckIcon } from \"@phosphor-icons/react/Check\";\nimport { LockIcon } from \"@phosphor-icons/react/Lock\";\nimport { XIcon } from \"@phosphor-icons/react/X\";\nimport type {\n\tComponentProps,\n\tComponentPropsWithoutRef,\n\tComponentRef,\n\tKeyboardEvent,\n\tReactNode,\n\tRefObject,\n} from \"react\";\nimport {\n\tcreateContext,\n\tforwardRef,\n\tuseCallback,\n\tuseContext,\n\tuseEffect,\n\tuseMemo,\n\tuseRef,\n} from \"react\";\nimport type { WithAsChild } from \"../../types/as-child.js\";\nimport { getPrefersReducedMotion } from \"../../hooks/use-prefers-reduced-motion.js\";\nimport { composeRefs } from \"../../utils/compose-refs/compose-refs.js\";\nimport { cx } from \"../../utils/cx/cx.js\";\nimport { Icon } from \"../icon/icon.js\";\nimport type { WithValidation } from \"../input/types.js\";\nimport { Separator } from \"../separator/separator.js\";\nimport { Slot } from \"../slot/index.js\";\n\n/** Type guard to safely narrow Ariakit store state to `string[]` without `as` assertions. */\nconst isStringArray = (value: unknown): value is string[] =>\n\tArray.isArray(value) && value.every((item) => typeof item === \"string\");\n\n/** Stable empty array used as a fallback for `selectedValues` to avoid creating new arrays on every render. */\nconst EMPTY_ARRAY: string[] = [];\n\nconst TriggerRefContext = createContext<RefObject<HTMLDivElement | null>>({ current: null });\n\n/**\n * Shared ref for locked values. Written by `TagValues` during render so that `Item` can read\n * it synchronously and prevent deselection of locked values from the popover.\n * Using a ref (instead of state) avoids re-renders and keeps the write safe in render.\n */\nconst LockedValuesContext = createContext<{ current: string[] }>({ current: [] });\n\n/**\n * Bridges keyboard-nav state between `TagValues` and `Input`, which are siblings in the tree\n * and cannot communicate via a context that either one provides — it must come from a shared\n * ancestor (`Root`). Both refs are written by one side and read by the other:\n * - `onInputKeyDownRef`: written by `TagValues`, called by `Input` on keydown\n * - `inputRef`: written by `Input` (registers its DOM node), read by `TagValues` (to focus it)\n */\ntype TagBridgeContextValue = {\n\tonInputKeyDownRef: { current: ((event: KeyboardEvent<HTMLInputElement>) => void) | undefined };\n\tinputRef: { current: HTMLInputElement | null };\n};\n\nconst TagBridgeContext = createContext<TagBridgeContextValue>({\n\tonInputKeyDownRef: { current: undefined },\n\tinputRef: { current: null },\n});\n\ntype MultiSelectProps = Primitive.ComboboxProviderProps<string[]>;\n\n/**\n * Root component for a multi-select combobox. Provides state management for\n * selecting multiple values with typeahead filtering.\n *\n * @example\n * ```tsx\n * <MultiSelect.Root>\n * <MultiSelect.Trigger>\n * <MultiSelect.TagValues />\n * <MultiSelect.Input placeholder=\"Select items...\" />\n * </MultiSelect.Trigger>\n * <MultiSelect.Content>\n * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n * <MultiSelect.Item value=\"banana\">Banana</MultiSelect.Item>\n * </MultiSelect.Content>\n * </MultiSelect.Root>\n * ```\n */\nconst Root = ({ children, defaultSelectedValue = [], ...props }: MultiSelectProps) => {\n\tconst triggerRef = useRef<HTMLDivElement | null>(null);\n\tconst onInputKeyDownRef = useRef<((event: KeyboardEvent<HTMLInputElement>) => void) | undefined>(\n\t\tundefined,\n\t);\n\tconst inputRef = useRef<HTMLInputElement | null>(null);\n\tconst lockedValuesRef = useRef<string[]>([]);\n\tconst tagBridge = useMemo(() => ({ onInputKeyDownRef, inputRef }), []);\n\n\treturn (\n\t\t<TriggerRefContext.Provider value={triggerRef}>\n\t\t\t<TagBridgeContext.Provider value={tagBridge}>\n\t\t\t\t<LockedValuesContext.Provider value={lockedValuesRef}>\n\t\t\t\t\t<Primitive.ComboboxProvider<string[]>\n\t\t\t\t\t\tdefaultSelectedValue={defaultSelectedValue}\n\t\t\t\t\t\t{...props}\n\t\t\t\t\t>\n\t\t\t\t\t\t{children}\n\t\t\t\t\t</Primitive.ComboboxProvider>\n\t\t\t\t</LockedValuesContext.Provider>\n\t\t\t</TagBridgeContext.Provider>\n\t\t</TriggerRefContext.Provider>\n\t);\n};\nRoot.displayName = \"MultiSelect\";\n\ntype MultiSelectTriggerProps = ComponentPropsWithoutRef<\"div\"> & WithValidation;\n\n/**\n * The trigger container for the multi-select. Wraps the input and selected\n * value tags in a styled container that looks like a form input.\n *\n * @example\n * ```tsx\n * <MultiSelect.Root>\n * <MultiSelect.Trigger>\n * <MultiSelect.TagValues />\n * <MultiSelect.Input placeholder=\"Select items...\" />\n * </MultiSelect.Trigger>\n * <MultiSelect.Content>\n * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n * </MultiSelect.Content>\n * </MultiSelect.Root>\n * ```\n */\nconst Trigger = forwardRef<HTMLDivElement, MultiSelectTriggerProps>(\n\t(\n\t\t{\n\t\t\t\"aria-invalid\": _ariaInvalid,\n\t\t\tclassName,\n\t\t\tchildren,\n\t\t\tonKeyDown,\n\t\t\tonMouseDown,\n\t\t\tvalidation: _validation,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst triggerRef = useContext(TriggerRefContext);\n\t\tconst { inputRef } = useContext(TagBridgeContext);\n\t\tconst store = Primitive.useComboboxContext();\n\t\tconst isInvalid = _ariaInvalid != null && _ariaInvalid !== \"false\";\n\t\tconst validation = isInvalid\n\t\t\t? \"error\"\n\t\t\t: typeof _validation === \"function\"\n\t\t\t\t? _validation()\n\t\t\t\t: _validation;\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\trole=\"group\"\n\t\t\t\tdata-slot=\"multi-select-trigger\"\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"cursor-text select-none font-sans text-sm\",\n\t\t\t\t\t\"border-form bg-form text-strong flex min-h-9 w-full flex-wrap items-center gap-1 rounded-md border px-3 py-1 has-[[data-slot=multi-select-tag]]:px-1\",\n\t\t\t\t\t\"has-focus:outline-hidden has-focus-within:ring-4 has-aria-expanded:ring-4\",\n\t\t\t\t\t\"has-focus-within:border-accent-600 has-focus-within:ring-focus-accent has-aria-expanded:border-accent-600 has-aria-expanded:ring-focus-accent\",\n\t\t\t\t\t\"data-validation-success:border-success-600 data-validation-success:has-focus-within:border-success-600 data-validation-success:has-focus-within:ring-focus-success data-validation-success:has-aria-expanded:border-success-600 data-validation-success:has-aria-expanded:ring-focus-success\",\n\t\t\t\t\t\"data-validation-warning:border-warning-600 data-validation-warning:has-focus-within:border-warning-600 data-validation-warning:has-focus-within:ring-focus-warning data-validation-warning:has-aria-expanded:border-warning-600 data-validation-warning:has-aria-expanded:ring-focus-warning\",\n\t\t\t\t\t\"data-validation-error:border-danger-600 data-validation-error:has-focus-within:border-danger-600 data-validation-error:has-focus-within:ring-focus-danger data-validation-error:has-aria-expanded:border-danger-600 data-validation-error:has-aria-expanded:ring-focus-danger\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tdata-validation={validation || undefined}\n\t\t\t\tonKeyDown={(event) => {\n\t\t\t\t\tif (event.key === \"Escape\" && store?.getState().open) {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\tstore.hide();\n\t\t\t\t\t}\n\t\t\t\t\tonKeyDown?.(event);\n\t\t\t\t}}\n\t\t\t\tonMouseDown={(event) => {\n\t\t\t\t\t// When clicking on non-interactive areas (padding, flex gaps between tags), prevent the\n\t\t\t\t\t// default mousedown behavior (which would cause text selection) and explicitly focus the\n\t\t\t\t\t// input. Clicks on buttons, the input itself, or tag spans are handled by those elements.\n\t\t\t\t\tif (\n\t\t\t\t\t\tevent.target instanceof HTMLElement &&\n\t\t\t\t\t\t!event.target.closest(\"button, input, [role='option']\")\n\t\t\t\t\t) {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\tinputRef.current?.focus();\n\t\t\t\t\t}\n\t\t\t\t\tonMouseDown?.(event);\n\t\t\t\t}}\n\t\t\t\tref={composeRefs(triggerRef, ref)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t);\n\t},\n);\nTrigger.displayName = \"MultiSelectTrigger\";\n\ntype TagProps = Omit<ComponentProps<\"span\">, \"children\"> & {\n\t/**\n\t * The value to display in the tag label.\n\t */\n\tvalue: string;\n\t/**\n\t * Called when the remove button is clicked.\n\t */\n\tonRemove?: () => void;\n\t/**\n\t * When true, the tag cannot be removed. The remove button is disabled and\n\t * Delete/Backspace key presses are ignored while the tag is focused.\n\t */\n\tlocked?: boolean;\n};\n\n/**\n * The default tag rendered inside `MultiSelect.TagValues` for each selected value.\n * Displays the value label with a remove button and full keyboard navigation support.\n *\n * Use this when building a custom `TagValues`-like component and you want the\n * default tag chrome with consistent styling.\n *\n * @example\n * ```tsx\n * <MultiSelect.Tag value=\"apple\" />\n * ```\n */\nconst Tag = forwardRef<HTMLSpanElement, TagProps>(\n\t({ className, value, onRemove, locked = false, onKeyDown, ...props }, ref) => {\n\t\tconst internalRef = useRef<HTMLSpanElement | null>(null);\n\n\t\treturn (\n\t\t\t<span\n\t\t\t\tref={composeRefs(internalRef, ref)}\n\t\t\t\trole=\"option\"\n\t\t\t\taria-selected\n\t\t\t\ttabIndex={-1}\n\t\t\t\tdata-slot=\"multi-select-tag\"\n\t\t\t\tdata-locked={locked || undefined}\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"cursor-default bg-neutral-500/10 border border-neutral-500/20 rounded-xs text-strong inline-flex items-center gap-1 pl-2 pr-0.5 py-0.5 text-sm font-normal\",\n\t\t\t\t\t\"focus-visible:outline-hidden focus-visible:border-accent-600/50 focus-visible:ring-3 focus-visible:ring-focus-accent\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tonKeyDown={(event) => {\n\t\t\t\t\tif (locked && (event.key === \"Backspace\" || event.key === \"Delete\")) {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\tshakeElement(event.currentTarget);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tonKeyDown?.(event);\n\t\t\t\t}}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{value}\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\taria-label={`Remove ${value}`}\n\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\taria-disabled={locked || undefined}\n\t\t\t\t\tclassName={cx(\n\t\t\t\t\t\t\"cursor-pointer text-strong/40 hover:bg-neutral-500/15 hover:text-strong rounded-xs p-0.5\",\n\t\t\t\t\t\t\"aria-disabled:cursor-default aria-disabled:hover:bg-transparent aria-disabled:hover:text-strong/40\",\n\t\t\t\t\t)}\n\t\t\t\t\tonClick={(event) => {\n\t\t\t\t\t\t// Prevent the click from bubbling to the trigger, which would reopen or refocus the combobox\n\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\tif (locked) {\n\t\t\t\t\t\t\t// Shake the tag to signal that removal is blocked\n\t\t\t\t\t\t\tconst tagElement = internalRef.current;\n\t\t\t\t\t\t\tif (tagElement) {\n\t\t\t\t\t\t\t\tshakeElement(tagElement);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tonRemove?.();\n\t\t\t\t\t}}\n\t\t\t\t\tonMouseDown={(event) => {\n\t\t\t\t\t\t// Prevent the input from losing focus on click, which would close the popover before the remove fires\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<Icon svg={locked ? <LockIcon /> : <XIcon weight=\"bold\" />} className=\"size-4\" />\n\t\t\t\t</button>\n\t\t\t</span>\n\t\t);\n\t},\n);\nTag.displayName = \"MultiSelectTag\";\n\n/**\n * Props passed to the children render function of `MultiSelect.TagValues`.\n * Spread these onto `MultiSelect.Tag` (or your own tag component) to\n * get the value, remove handler, locked state, and ref-based keyboard-nav\n * registration all wired up automatically.\n *\n * Pre-wired handlers included:\n * - `onKeyDown` — arrow-key nav between tags, Backspace/Delete to remove\n * - `onClick` — focuses the tag and ensures the popover opens/stays open\n */\ntype TagRenderProps = TagProps & {\n\t/** Ref callback — forward this to the tag element to enable keyboard navigation between tags. */\n\tref: (node: HTMLSpanElement | null) => void;\n};\n\ntype MultiSelectTagValuesProps = {\n\t/**\n\t * Values that cannot be removed. Locked tags have their remove button disabled,\n\t * respond to Backspace/Delete key presses with a shake animation, and shake when\n\t * Backspace is pressed on an empty input.\n\t *\n\t * The `locked` state is also forwarded to the render function via `props.locked`\n\t * so custom tag components receive it automatically.\n\t */\n\tlockedValues?: string[];\n\t/**\n\t * Optional render function for each tag. Receives `{ value, onRemove, locked, ref }` —\n\t * spread these onto `MultiSelect.Tag` (or your own element) for full keyboard-nav support.\n\t * When omitted, the default `MultiSelect.Tag` is rendered for each selected value.\n\t *\n\t * @example\n\t * ```tsx\n\t * <MultiSelect.TagValues lockedValues={[\"global\"]}>\n\t * {(props) => (\n\t * <MultiSelect.Tag key={props.value} {...props} />\n\t * )}\n\t * </MultiSelect.TagValues>\n\t * ```\n\t */\n\tchildren?: (props: TagRenderProps) => ReactNode;\n};\n\n/**\n * Renders the selected values as removable tags. Place this inside\n * `MultiSelect.Trigger`, followed by `MultiSelect.Input`.\n *\n * @example\n * ```tsx\n * <MultiSelect.Root>\n * <MultiSelect.Trigger>\n * <MultiSelect.TagValues />\n * <MultiSelect.Input placeholder=\"Select items...\" />\n * </MultiSelect.Trigger>\n * <MultiSelect.Content>\n * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n * </MultiSelect.Content>\n * </MultiSelect.Root>\n * ```\n */\nconst TagValues = ({ children, lockedValues = [] }: MultiSelectTagValuesProps) => {\n\tconst store = Primitive.useComboboxContext();\n\tconst rawSelectedValue = Primitive.useStoreState(store, \"selectedValue\");\n\tconst selectedValues = isStringArray(rawSelectedValue) ? rawSelectedValue : undefined;\n\tconst selectedArray = selectedValues ?? EMPTY_ARRAY;\n\t// Keep refs in sync so requestAnimationFrame callbacks always read fresh state\n\t// instead of closing over stale values from the render they were scheduled in.\n\tconst selectedArrayRef = useRef<string[]>(selectedArray);\n\tselectedArrayRef.current = selectedArray;\n\t// Use the shared LockedValuesContext ref so Item can also read locked values\n\t// without a separate prop. Writing a ref during render is safe here because\n\t// refs are mutable and don't trigger re-renders.\n\tconst lockedValuesRef = useContext(LockedValuesContext);\n\tlockedValuesRef.current = lockedValues;\n\tconst lockedValuesSet = useMemo(() => new Set(lockedValues), [lockedValues]);\n\tconst tagRefs = useRef<Map<string, HTMLSpanElement>>(new Map());\n\tconst { onInputKeyDownRef, inputRef } = useContext(TagBridgeContext);\n\t// Track pending rAF IDs so we can cancel them on unmount and avoid calling\n\t// focus() on detached DOM nodes if the component unmounts mid-frame.\n\tconst pendingRafsRef = useRef<Set<number>>(new Set());\n\tuseEffect(\n\t\t() => () => {\n\t\t\tpendingRafsRef.current.forEach(cancelAnimationFrame);\n\t\t},\n\t\t[],\n\t);\n\tconst raf = (callback: () => void): void => {\n\t\tlet id: number;\n\t\tid = requestAnimationFrame(() => {\n\t\t\t// Remove the id once the rAF has fired so the set doesn't grow unbounded.\n\t\t\tpendingRafsRef.current.delete(id);\n\t\t\tcallback();\n\t\t});\n\t\tpendingRafsRef.current.add(id);\n\t};\n\n\tconst removeValue = (value: string) => {\n\t\tif (store) {\n\t\t\tconst selected = store.getState().selectedValue;\n\t\t\tif (!isStringArray(selected)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tstore.setSelectedValue(selected.filter((v) => v !== value));\n\t\t}\n\t};\n\n\tconst focusTag = (index: number) => {\n\t\tconst value = selectedArrayRef.current[index];\n\t\tif (value == null) {\n\t\t\treturn;\n\t\t}\n\t\tconst tagElement = tagRefs.current.get(value);\n\t\tif (tagElement) {\n\t\t\ttagElement.focus();\n\t\t\t// Keep the popover open while a tag is focused. Ariakit closes the\n\t\t\t// popover when the combobox input loses focus, so we reopen it here.\n\t\t\tstore?.show();\n\t\t}\n\t};\n\n\tconst focusInput = () => {\n\t\tinputRef.current?.focus();\n\t};\n\n\tconst handleTagKeyDown = (event: KeyboardEvent<HTMLSpanElement>, index: number) => {\n\t\tconst value = selectedArray[index];\n\t\tswitch (event.key) {\n\t\t\tcase \"ArrowLeft\": {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tif (index > 0) {\n\t\t\t\t\tfocusTag(index - 1);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"ArrowRight\": {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tif (index < selectedArray.length - 1) {\n\t\t\t\t\tfocusTag(index + 1);\n\t\t\t\t} else {\n\t\t\t\t\tfocusInput();\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"Backspace\":\n\t\t\tcase \"Delete\": {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tif (value != null) {\n\t\t\t\t\t// Respect locked values: shake instead of removing when locked.\n\t\t\t\t\tif (lockedValuesSet.has(value)) {\n\t\t\t\t\t\tconst tagElement = tagRefs.current.get(value);\n\t\t\t\t\t\tif (tagElement) {\n\t\t\t\t\t\t\tshakeElement(tagElement);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tremoveValue(value);\n\t\t\t\t\t// After removal, the array shifts. Focus the next logical tag or the input.\n\t\t\t\t\tif (event.key === \"Backspace\") {\n\t\t\t\t\t\tif (index > 0) {\n\t\t\t\t\t\t\t// Focus the previous tag (will have same index - 1 after removal)\n\t\t\t\t\t\t\t// We need to wait for the next render, so use requestAnimationFrame\n\t\t\t\t\t\t\tconst prevIndex = index - 1;\n\t\t\t\t\t\t\traf(() => focusTag(prevIndex));\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\traf(() => {\n\t\t\t\t\t\t\t\tif (selectedArrayRef.current.length > 0) {\n\t\t\t\t\t\t\t\t\tfocusTag(0);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tfocusInput();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Delete: move focus right\n\t\t\t\t\t\traf(() => {\n\t\t\t\t\t\t\t// index stays the same since the item at `index` was removed and the next one slides in\n\t\t\t\t\t\t\tif (index < selectedArrayRef.current.length) {\n\t\t\t\t\t\t\t\tfocusTag(index);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tfocusInput();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"ArrowUp\":\n\t\t\tcase \"ArrowDown\": {\n\t\t\t\t// Don't scroll the page. Instead, focus the input and forward the key\n\t\t\t\t// to Ariakit so it navigates the popover list.\n\t\t\t\tevent.preventDefault();\n\t\t\t\tfocusInput();\n\t\t\t\tinputRef.current?.dispatchEvent(\n\t\t\t\t\tnew KeyboardEvent(\"keydown\", {\n\t\t\t\t\t\tkey: event.key,\n\t\t\t\t\t\tbubbles: true,\n\t\t\t\t\t\tcancelable: true,\n\t\t\t\t\t\tshiftKey: event.shiftKey,\n\t\t\t\t\t\tctrlKey: event.ctrlKey,\n\t\t\t\t\t\tmetaKey: event.metaKey,\n\t\t\t\t\t\taltKey: event.altKey,\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\t// If a printable character is typed while a tag is focused, jump to input\n\t\t\t\tif (event.key.length === 1 && !event.ctrlKey && !event.metaKey) {\n\t\t\t\t\tfocusInput();\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t};\n\n\tconst handleInputKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n\t\tif (\n\t\t\tevent.key === \"ArrowLeft\" &&\n\t\t\tevent.currentTarget.selectionStart === 0 &&\n\t\t\tevent.currentTarget.selectionEnd === 0 &&\n\t\t\tselectedArray.length > 0\n\t\t) {\n\t\t\tevent.preventDefault();\n\t\t\tfocusTag(selectedArray.length - 1);\n\t\t\treturn;\n\t\t}\n\t\tif (event.key === \"Backspace\" && event.currentTarget.value === \"\" && selectedArray.length > 0) {\n\t\t\tconst lastValue = selectedArray[selectedArray.length - 1];\n\t\t\tif (lastValue != null) {\n\t\t\t\tif (lockedValuesRef.current.includes(lastValue)) {\n\t\t\t\t\t// The last tag is locked — shake it to signal that removal is blocked.\n\t\t\t\t\tconst tagElement = tagRefs.current.get(lastValue);\n\t\t\t\t\tif (tagElement) {\n\t\t\t\t\t\tshakeElement(tagElement);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tremoveValue(lastValue);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t// Write the latest handler into the bridge ref so Input can call it via onKeyDown.\n\t// Assigned directly during render (safe — refs are mutable and don't trigger re-renders).\n\tonInputKeyDownRef.current = handleInputKeyDown;\n\n\treturn (\n\t\t<>\n\t\t\t{selectedArray.map((value, index) => {\n\t\t\t\tconst tagOptionProps: TagRenderProps = {\n\t\t\t\t\tvalue,\n\t\t\t\t\tlocked: lockedValuesSet.has(value),\n\t\t\t\t\tonRemove: () => {\n\t\t\t\t\t\t// Respect locked values: shake instead of removing when locked.\n\t\t\t\t\t\t// This guards custom tag renderers that call onRemove directly.\n\t\t\t\t\t\tif (lockedValuesSet.has(value)) {\n\t\t\t\t\t\t\tconst tagElement = tagRefs.current.get(value);\n\t\t\t\t\t\t\tif (tagElement) {\n\t\t\t\t\t\t\t\tshakeElement(tagElement);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tremoveValue(value);\n\t\t\t\t\t},\n\t\t\t\t\tref: (node: HTMLSpanElement | null) => {\n\t\t\t\t\t\tif (node) {\n\t\t\t\t\t\t\ttagRefs.current.set(value, node);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttagRefs.current.delete(value);\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tonKeyDown: (event: KeyboardEvent<HTMLSpanElement>) => handleTagKeyDown(event, index),\n\t\t\t\t\t// Ensure the popover opens/stays open when a tag is clicked,\n\t\t\t\t\t// including when the component was fully blurred before the click.\n\t\t\t\t\tonClick: () => focusTag(index),\n\t\t\t\t};\n\n\t\t\t\tif (children) {\n\t\t\t\t\treturn children(tagOptionProps);\n\t\t\t\t}\n\n\t\t\t\treturn <Tag key={value} {...tagOptionProps} />;\n\t\t\t})}\n\t\t</>\n\t);\n};\nTagValues.displayName = \"MultiSelectTagValues\";\n\ntype MultiSelectInputProps = Omit<Primitive.ComboboxProps, \"render\"> & {\n\t/**\n\t * Called with the raw string value whenever the input text changes.\n\t * Use this to drive external filtering (e.g. with matchSorter) without\n\t * having to unwrap the DOM event. A convenience alternative to `onChange`.\n\t */\n\tonValueChange?: (value: string) => void;\n};\n\n/**\n * The combobox input for filtering items. Place this inside `MultiSelect.Trigger`,\n * after `MultiSelect.TagValues`.\n *\n * @example\n * ```tsx\n * <MultiSelect.Root>\n * <MultiSelect.Trigger>\n * <MultiSelect.TagValues />\n * <MultiSelect.Input placeholder=\"Select items...\" />\n * </MultiSelect.Trigger>\n * <MultiSelect.Content>\n * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n * </MultiSelect.Content>\n * </MultiSelect.Root>\n * ```\n */\nconst Input = forwardRef<ComponentRef<\"input\">, MultiSelectInputProps>(\n\t(\n\t\t{ className, onBlur, onChange, onFocus, onKeyDown, onValueChange, placeholder, ...props },\n\t\tref,\n\t) => {\n\t\tconst store = Primitive.useComboboxContext();\n\t\tconst { onInputKeyDownRef, inputRef } = useContext(TagBridgeContext);\n\t\tconst rawSelectedValue = Primitive.useStoreState(store, \"selectedValue\");\n\t\tconst selectedValues = isStringArray(rawSelectedValue) ? rawSelectedValue : undefined;\n\t\tconst hasSelectedValues = (selectedValues?.length ?? 0) > 0;\n\n\t\treturn (\n\t\t\t<Primitive.Combobox\n\t\t\t\tautoSelect\n\t\t\t\tdata-slot=\"multi-select-input\"\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"pointer-coarse:text-base min-w-20 flex-1 select-text border-0 bg-transparent text-sm outline-hidden\",\n\t\t\t\t\t\"placeholder:select-none placeholder:text-placeholder\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tonChange={(event) => {\n\t\t\t\t\tonValueChange?.(event.target.value);\n\t\t\t\t\tonChange?.(event);\n\t\t\t\t}}\n\t\t\t\tonKeyDown={(event) => {\n\t\t\t\t\tonInputKeyDownRef.current?.(event);\n\t\t\t\t\tonKeyDown?.(event);\n\t\t\t\t}}\n\t\t\t\tonBlur={(event) => {\n\t\t\t\t\t// When focus moves from the input to a tag, Ariakit would normally\n\t\t\t\t\t// close the popover because the combobox input lost focus. Keep it\n\t\t\t\t\t// open so the user can see the list while navigating tags.\n\t\t\t\t\tif (\n\t\t\t\t\t\tevent.relatedTarget instanceof HTMLElement &&\n\t\t\t\t\t\tevent.relatedTarget.closest('[data-slot=\"multi-select-tag\"]')\n\t\t\t\t\t) {\n\t\t\t\t\t\tstore?.show();\n\t\t\t\t\t}\n\t\t\t\t\tonBlur?.(event);\n\t\t\t\t}}\n\t\t\t\tonFocus={(event) => {\n\t\t\t\t\t// Ariakit doesn't always open the popover on focus when the input is\n\t\t\t\t\t// already mounted (e.g. returning focus from a tag). Force it open.\n\t\t\t\t\tstore?.show();\n\t\t\t\t\tonFocus?.(event);\n\t\t\t\t}}\n\t\t\t\tplaceholder={hasSelectedValues ? undefined : placeholder}\n\t\t\t\t// Register the input's DOM node in the bridge so TagValues can focus it for keyboard nav.\n\t\t\t\tref={composeRefs(inputRef, ref)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t);\n\t},\n);\nInput.displayName = \"MultiSelectInput\";\n\ntype MultiSelectContentProps = Omit<Primitive.ComboboxPopoverProps, \"render\"> & WithAsChild;\n\n/**\n * Renders a popover that contains multi-select content, such as items, groups,\n * and separators. Opens below the trigger.\n *\n * @example\n * ```tsx\n * <MultiSelect.Root>\n * <MultiSelect.Trigger>\n * <MultiSelect.TagValues />\n * <MultiSelect.Input placeholder=\"Select items...\" />\n * </MultiSelect.Trigger>\n * <MultiSelect.Content>\n * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n * <MultiSelect.Item value=\"banana\">Banana</MultiSelect.Item>\n * </MultiSelect.Content>\n * </MultiSelect.Root>\n * ```\n */\nconst Content = forwardRef<ComponentRef<\"div\">, MultiSelectContentProps>(\n\t(\n\t\t{\n\t\t\tasChild = false,\n\t\t\tbackdrop = false,\n\t\t\tchildren,\n\t\t\tclassName,\n\t\t\tmodal = true,\n\t\t\tportalElement,\n\t\t\tsameWidth = true,\n\t\t\tunmountOnHide = true,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst triggerRef = useContext(TriggerRefContext);\n\n\t\tconst getAnchorRect = useCallback(() => {\n\t\t\treturn triggerRef.current?.getBoundingClientRect() ?? null;\n\t\t}, [triggerRef]);\n\n\t\tconst getPortalElement = useCallback(\n\t\t\t(element: HTMLElement) => {\n\t\t\t\tif (typeof portalElement === \"function\") {\n\t\t\t\t\treturn portalElement(element);\n\t\t\t\t}\n\n\t\t\t\treturn (\n\t\t\t\t\tportalElement ??\n\t\t\t\t\ttriggerRef.current?.closest<HTMLElement>(\"[data-mantle-modal-content]\") ??\n\t\t\t\t\telement.ownerDocument.body\n\t\t\t\t);\n\t\t\t},\n\t\t\t[portalElement, triggerRef],\n\t\t);\n\n\t\tconst hideOnInteractOutside = useCallback(\n\t\t\t(event: Event) => {\n\t\t\t\t// Keep the popover open when interacting with any part of the trigger\n\t\t\t\t// (tags, buttons, input, padding). Ariakit would otherwise close on any\n\t\t\t\t// mousedown outside the popover — including tag clicks.\n\t\t\t\tif (event.target instanceof Node && triggerRef.current?.contains(event.target)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t},\n\t\t\t[triggerRef],\n\t\t);\n\n\t\treturn (\n\t\t\t<Primitive.ComboboxPopover\n\t\t\t\tdata-slot=\"multi-select-content\"\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"border-popover bg-popover relative z-50 max-h-96 min-w-32 scrollbar overflow-y-scroll overflow-x-hidden overscroll-y-none rounded-md border shadow-md pt-1 pb-1 has-data-content-footer:pb-0 font-sans flex flex-col gap-px focus:outline-hidden\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tbackdrop={backdrop}\n\t\t\t\tgetAnchorRect={getAnchorRect}\n\t\t\t\tgutter={4}\n\t\t\t\thideOnInteractOutside={hideOnInteractOutside}\n\t\t\t\tmodal={modal}\n\t\t\t\tportalElement={getPortalElement}\n\t\t\t\tref={ref}\n\t\t\t\trender={\n\t\t\t\t\tasChild ? ({ ref, ...childProps }) => <Slot ref={ref} {...childProps} /> : undefined\n\t\t\t\t}\n\t\t\t\tsameWidth={sameWidth}\n\t\t\t\tunmountOnHide={unmountOnHide}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</Primitive.ComboboxPopover>\n\t\t);\n\t},\n);\nContent.displayName = \"MultiSelectContent\";\n\ntype MultiSelectItemProps = Omit<Primitive.ComboboxItemProps, \"render\"> & WithAsChild;\n\n/**\n * Renders a selectable item inside a `MultiSelect.Content` component.\n * Items display a checkbox indicator when selected.\n *\n * @example\n * ```tsx\n * <MultiSelect.Content>\n * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n * <MultiSelect.Item value=\"banana\">Banana</MultiSelect.Item>\n * </MultiSelect.Content>\n * ```\n */\nconst Item = forwardRef<ComponentRef<\"div\">, MultiSelectItemProps>(\n\t(\n\t\t{ asChild = false, children, className, focusOnHover = true, value, onClick, ...props },\n\t\tref,\n\t) => {\n\t\tconst lockedValuesRef = useContext(LockedValuesContext);\n\t\tconst isLocked = value != null && lockedValuesRef.current.includes(value);\n\n\t\treturn (\n\t\t\t<Primitive.ComboboxItem\n\t\t\t\tdata-slot=\"multi-select-item\"\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"relative mx-1 cursor-pointer rounded-md pl-2 pr-8 py-1.5 text-strong text-sm font-normal flex min-w-0 items-center gap-2\",\n\t\t\t\t\t\"[[role=option]+&]:mt-px\",\n\t\t\t\t\t\"data-active-item:bg-active-menu-item\",\n\t\t\t\t\t\"aria-disabled:opacity-50\",\n\t\t\t\t\t\"aria-selected:bg-selected-menu-item aria-selected:data-active-item:bg-active-selected-menu-item\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tfocusOnHover={focusOnHover}\n\t\t\t\tonClick={(event) => {\n\t\t\t\t\t// Prevent Ariakit from toggling off a locked value.\n\t\t\t\t\t// Ariakit checks event.defaultPrevented before executing its selection logic.\n\t\t\t\t\tif (isLocked) {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tonClick?.(event);\n\t\t\t\t}}\n\t\t\t\tref={ref}\n\t\t\t\trender={\n\t\t\t\t\tasChild ? ({ ref, ...childProps }) => <Slot ref={ref} {...childProps} /> : undefined\n\t\t\t\t}\n\t\t\t\tresetValueOnSelect\n\t\t\t\tvalue={value}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t\t<Primitive.ComboboxItemCheck className=\"absolute right-2 flex h-3.5 w-3.5 items-center justify-center\">\n\t\t\t\t\t<Icon svg={<CheckIcon weight=\"bold\" />} className=\"size-4 text-accent-600\" />\n\t\t\t\t</Primitive.ComboboxItemCheck>\n\t\t\t</Primitive.ComboboxItem>\n\t\t);\n\t},\n);\nItem.displayName = \"MultiSelectItem\";\n\ntype MultiSelectGroupProps = Omit<Primitive.ComboboxGroupProps, \"render\"> & WithAsChild;\n\n/**\n * Renders a group for MultiSelect.Item elements.\n *\n * @example\n * ```tsx\n * <MultiSelect.Content>\n * <MultiSelect.Group>\n * <MultiSelect.GroupLabel>Fruits</MultiSelect.GroupLabel>\n * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n * <MultiSelect.Item value=\"banana\">Banana</MultiSelect.Item>\n * </MultiSelect.Group>\n * </MultiSelect.Content>\n * ```\n */\nconst Group = forwardRef<ComponentRef<\"div\">, MultiSelectGroupProps>(\n\t({ asChild = false, children, ...props }, ref) => {\n\t\treturn (\n\t\t\t<Primitive.ComboboxGroup\n\t\t\t\tdata-slot=\"multi-select-group\"\n\t\t\t\tclassName=\"mx-1\"\n\t\t\t\tref={ref}\n\t\t\t\trender={\n\t\t\t\t\tasChild ? ({ ref, ...childProps }) => <Slot ref={ref} {...childProps} /> : undefined\n\t\t\t\t}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</Primitive.ComboboxGroup>\n\t\t);\n\t},\n);\nGroup.displayName = \"MultiSelectGroup\";\n\ntype MultiSelectGroupLabelProps = Omit<Primitive.ComboboxGroupLabelProps, \"render\"> & WithAsChild;\n\n/**\n * Renders a label in a multi-select group.\n *\n * @example\n * ```tsx\n * <MultiSelect.Content>\n * <MultiSelect.Group>\n * <MultiSelect.GroupLabel>Fruits</MultiSelect.GroupLabel>\n * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n * </MultiSelect.Group>\n * </MultiSelect.Content>\n * ```\n */\nconst GroupLabel = forwardRef<ComponentRef<\"div\">, MultiSelectGroupLabelProps>(\n\t({ asChild = false, children, className, ...props }, ref) => {\n\t\treturn (\n\t\t\t<Primitive.ComboboxGroupLabel\n\t\t\t\tdata-slot=\"multi-select-group-label\"\n\t\t\t\tclassName={cx(\"text-muted px-2 py-1 text-xs font-medium\", className)}\n\t\t\t\tref={ref}\n\t\t\t\trender={\n\t\t\t\t\tasChild ? ({ ref, ...childProps }) => <Slot ref={ref} {...childProps} /> : undefined\n\t\t\t\t}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</Primitive.ComboboxGroupLabel>\n\t\t);\n\t},\n);\nGroupLabel.displayName = \"MultiSelectGroupLabel\";\n\ntype MultiSelectGroupDescriptionProps = ComponentPropsWithoutRef<\"p\">;\n\n/**\n * Renders a description below a `MultiSelect.GroupLabel` inside a `MultiSelect.Group`.\n * Provides context about the group's purpose or constraints.\n *\n * @example\n * ```tsx\n * <MultiSelect.Group>\n * <MultiSelect.GroupLabel>Regional Aliases</MultiSelect.GroupLabel>\n * <MultiSelect.GroupDescription>\n * Include all points of presence that are geographically within the region.\n * </MultiSelect.GroupDescription>\n * <MultiSelect.Item value=\"global\">global</MultiSelect.Item>\n * </MultiSelect.Group>\n * ```\n */\nconst GroupDescription = forwardRef<HTMLParagraphElement, MultiSelectGroupDescriptionProps>(\n\t({ className, children, ...props }, ref) => {\n\t\treturn (\n\t\t\t<p\n\t\t\t\tdata-slot=\"multi-select-group-description\"\n\t\t\t\tclassName={cx(\"text-muted px-2 pb-1 text-xs\", className)}\n\t\t\t\tref={ref}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</p>\n\t\t);\n\t},\n);\nGroupDescription.displayName = \"MultiSelectGroupDescription\";\n\n/**\n * Renders a separator between MultiSelect.Items or MultiSelect.Groups.\n *\n * @example\n * ```tsx\n * <MultiSelect.Content>\n * <MultiSelect.Group>\n * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n * </MultiSelect.Group>\n * <MultiSelect.Separator />\n * <MultiSelect.Group>\n * <MultiSelect.Item value=\"carrot\">Carrot</MultiSelect.Item>\n * </MultiSelect.Group>\n * </MultiSelect.Content>\n * ```\n */\nconst MultiSelectSeparatorComponent = forwardRef<\n\tComponentRef<\"div\">,\n\tComponentPropsWithoutRef<typeof Separator>\n>(({ className, ...props }, ref) => (\n\t<Separator\n\t\tdata-slot=\"multi-select-separator\"\n\t\tref={ref}\n\t\tclassName={cx(\"my-1 w-auto\", className)}\n\t\t{...props}\n\t/>\n));\nMultiSelectSeparatorComponent.displayName = \"MultiSelectSeparator\";\n\ntype MultiSelectEmptyProps = ComponentPropsWithoutRef<\"div\">;\n\n/**\n * Renders a message when no items match the current filter.\n *\n * @example\n * ```tsx\n * <MultiSelect.Content>\n * {matches.length === 0 && (\n * <MultiSelect.Empty>No results found</MultiSelect.Empty>\n * )}\n * </MultiSelect.Content>\n * ```\n */\nconst Empty = forwardRef<HTMLDivElement, MultiSelectEmptyProps>(\n\t({ className, children, ...props }, ref) => {\n\t\treturn (\n\t\t\t<div\n\t\t\t\tdata-slot=\"multi-select-empty\"\n\t\t\t\tclassName={cx(\"mx-1 text-muted px-2 py-6 text-center text-sm\", className)}\n\t\t\t\tref={ref}\n\t\t\t\trole=\"presentation\"\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t);\n\t},\n);\nEmpty.displayName = \"MultiSelectEmpty\";\n\ntype MultiSelectContentFooterProps = ComponentPropsWithoutRef<\"div\">;\n\n/**\n * Renders a sticky footer pinned to the bottom inside `MultiSelect.Content`,\n * with a separator border at the top.\n *\n * @example\n * ```tsx\n * <MultiSelect.Content>\n * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n * <MultiSelect.ContentFooter>\n * <p>Upgrade to unlock more options.</p>\n * <Button>Upgrade</Button>\n * </MultiSelect.ContentFooter>\n * </MultiSelect.Content>\n * ```\n */\nconst ContentFooter = forwardRef<HTMLDivElement, MultiSelectContentFooterProps>(\n\t({ className, children, ...props }, ref) => {\n\t\treturn (\n\t\t\t<div\n\t\t\t\tref={ref}\n\t\t\t\tdata-slot=\"multi-select-content-footer\"\n\t\t\t\tdata-content-footer\n\t\t\t\tclassName={cx(\"bg-popover sticky bottom-0 border-t border-popover\", className)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t);\n\t},\n);\nContentFooter.displayName = \"MultiSelectContentFooter\";\n\n/**\n * A multi-select combobox that allows users to select multiple values with\n * typeahead filtering. Selected values are displayed as removable tags.\n *\n * Built on top of Ariakit's Combobox primitives with full keyboard support\n * and WAI-ARIA compliance.\n *\n * @see https://www.w3.org/WAI/ARIA/apg/patterns/combobox/\n * @see https://ariakit.org/components/combobox\n *\n * @example\n * ```tsx\n * <MultiSelect.Root>\n * <MultiSelect.Trigger>\n * <MultiSelect.TagValues />\n * <MultiSelect.Input placeholder=\"Select items...\" />\n * </MultiSelect.Trigger>\n * <MultiSelect.Content>\n * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n * <MultiSelect.Item value=\"banana\">Banana</MultiSelect.Item>\n * <MultiSelect.Item value=\"cherry\">Cherry</MultiSelect.Item>\n * </MultiSelect.Content>\n * </MultiSelect.Root>\n * ```\n */\nconst MultiSelect = {\n\t/**\n\t * Root component for a multi-select combobox. Provides state management for\n\t * selecting multiple values with typeahead filtering.\n\t *\n\t * @example\n\t * ```tsx\n\t * <MultiSelect.Root>\n\t * <MultiSelect.Trigger>\n\t * <MultiSelect.TagValues />\n\t * <MultiSelect.Input placeholder=\"Select items...\" />\n\t * </MultiSelect.Trigger>\n\t * <MultiSelect.Content>\n\t * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n\t * </MultiSelect.Content>\n\t * </MultiSelect.Root>\n\t * ```\n\t */\n\tRoot,\n\t/**\n\t * The trigger container for the multi-select. Wraps the tags and input\n\t * in a styled container.\n\t *\n\t * @example\n\t * ```tsx\n\t * <MultiSelect.Trigger>\n\t * <MultiSelect.TagValues />\n\t * <MultiSelect.Input placeholder=\"Select items...\" />\n\t * </MultiSelect.Trigger>\n\t * ```\n\t */\n\tTrigger,\n\t/**\n\t * Renders the selected values as removable tags. Place this inside\n\t * `MultiSelect.Trigger`, followed by `MultiSelect.Input`.\n\t *\n\t * Use `lockedValues` to prevent specific tags from being removed. Locked tags\n\t * have their remove button disabled and shake when Backspace is pressed.\n\t *\n\t * @example\n\t * ```tsx\n\t * // Default tags with locking\n\t * <MultiSelect.TagValues lockedValues={[\"global\"]} />\n\t *\n\t * // Custom tags via children render function — locked is forwarded via props\n\t * <MultiSelect.TagValues lockedValues={[\"global\"]}>\n\t * {(props) => (\n\t * <MultiSelect.Tag key={props.value} {...props} />\n\t * )}\n\t * </MultiSelect.TagValues>\n\t * ```\n\t */\n\tTagValues,\n\t/**\n\t * The combobox input for filtering items. Place this inside\n\t * `MultiSelect.Trigger`, after `MultiSelect.TagValues`.\n\t *\n\t * @example\n\t * ```tsx\n\t * <MultiSelect.Input placeholder=\"Select items...\" />\n\t * ```\n\t */\n\tInput,\n\t/**\n\t * The default tag rendered inside `MultiSelect.TagValues` for each selected value.\n\t * Displays the value label with a remove button and keyboard navigation support.\n\t *\n\t * @example\n\t * ```tsx\n\t * <MultiSelect.Tag\n\t * value=\"apple\"\n\t * onRemove={() => removeValue(\"apple\")}\n\t * />\n\t * ```\n\t */\n\tTag,\n\t/**\n\t * Renders a popover that contains multi-select content.\n\t *\n\t * @example\n\t * ```tsx\n\t * <MultiSelect.Content>\n\t * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n\t * </MultiSelect.Content>\n\t * ```\n\t */\n\tContent,\n\t/**\n\t * Renders a sticky footer pinned to the bottom inside `MultiSelect.Content`,\n\t * with a separator border at the top.\n\t *\n\t * @example\n\t * ```tsx\n\t * <MultiSelect.ContentFooter>\n\t * <p>Upgrade to unlock more options.</p>\n\t * </MultiSelect.ContentFooter>\n\t * ```\n\t */\n\tContentFooter,\n\t/**\n\t * Renders a selectable item with a checkbox indicator inside a `MultiSelect.Content`.\n\t *\n\t * @example\n\t * ```tsx\n\t * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n\t * ```\n\t */\n\tItem,\n\t/**\n\t * Renders a group for MultiSelect.Item elements.\n\t *\n\t * @example\n\t * ```tsx\n\t * <MultiSelect.Group>\n\t * <MultiSelect.GroupLabel>Fruits</MultiSelect.GroupLabel>\n\t * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n\t * </MultiSelect.Group>\n\t * ```\n\t */\n\tGroup,\n\t/**\n\t * Renders a label in a multi-select group.\n\t *\n\t * @example\n\t * ```tsx\n\t * <MultiSelect.GroupLabel>Fruits</MultiSelect.GroupLabel>\n\t * ```\n\t */\n\tGroupLabel,\n\t/**\n\t * Renders a description below a `MultiSelect.GroupLabel` inside a `MultiSelect.Group`.\n\t *\n\t * @example\n\t * ```tsx\n\t * <MultiSelect.GroupDescription>\n\t * Include all points of presence within the region.\n\t * </MultiSelect.GroupDescription>\n\t * ```\n\t */\n\tGroupDescription,\n\t/**\n\t * Renders a separator between items or groups.\n\t *\n\t * @example\n\t * ```tsx\n\t * <MultiSelect.Separator />\n\t * ```\n\t */\n\tSeparator: MultiSelectSeparatorComponent,\n\t/**\n\t * Renders a message when no items match the current filter.\n\t *\n\t * @example\n\t * ```tsx\n\t * <MultiSelect.Empty>No results found</MultiSelect.Empty>\n\t * ```\n\t */\n\tEmpty,\n} as const;\n\nexport {\n\t//,\n\tMultiSelect,\n};\n\n/**\n * Shakes an element left-right to signal that an action was blocked\n * (e.g. pressing Backspace/Delete on a locked tag). No-ops when the user\n * has enabled reduced motion in their OS/browser accessibility settings.\n */\nfunction shakeElement(element: HTMLElement): void {\n\t// Skip the animation when the user has opted into reduced motion.\n\t// Called from event handlers only, so reading the media query imperatively\n\t// is safe and gives the freshest value without any hook plumbing.\n\tif (getPrefersReducedMotion()) {\n\t\treturn;\n\t}\n\n\telement.animate(\n\t\t[\n\t\t\t{ transform: \"translateX(0)\" },\n\t\t\t{ transform: \"translateX(-4px)\" },\n\t\t\t{ transform: \"translateX(4px)\" },\n\t\t\t{ transform: \"translateX(-4px)\" },\n\t\t\t{ transform: \"translateX(4px)\" },\n\t\t\t{ transform: \"translateX(0)\" },\n\t\t],\n\t\t{ duration: 300, easing: \"ease-in-out\" },\n\t);\n}\n"],"mappings":"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"}
@@ -1,9 +1,9 @@
1
- import { t as WithAsChild } from "./as-child-XMVTepJu.js";
2
- import { t as ButtonGroup } from "./index-ViSCOUrU.js";
3
- import { t as Select } from "./select-BkvbNKQ7.js";
4
- import * as react from "react";
1
+ import { t as WithAsChild } from "./as-child-CRRsxi3Y.js";
2
+ import { t as ButtonGroup } from "./index-Cj2NX2Dg.js";
3
+ import { t as Select } from "./select-DJmjfGjt.js";
4
+ import * as _$react from "react";
5
5
  import { ComponentProps } from "react";
6
- import * as react_jsx_runtime0 from "react/jsx-runtime";
6
+ import * as _$react_jsx_runtime0 from "react/jsx-runtime";
7
7
 
8
8
  //#region src/components/pagination/cursor-pagination.d.ts
9
9
  type CursorPaginationProps = ComponentProps<"div"> & {
@@ -59,7 +59,7 @@ declare function PageSizeValue({
59
59
  asChild,
60
60
  className,
61
61
  ...props
62
- }: CursorPageSizeValueProps): react_jsx_runtime0.JSX.Element;
62
+ }: CursorPageSizeValueProps): _$react_jsx_runtime0.JSX.Element;
63
63
  declare namespace PageSizeValue {
64
64
  var displayName: string;
65
65
  }
@@ -106,7 +106,7 @@ declare const CursorPagination: {
106
106
  * </CursorPagination.Root>
107
107
  * ```
108
108
  */
109
- readonly Root: react.ForwardRefExoticComponent<Omit<CursorPaginationProps, "ref"> & react.RefAttributes<HTMLDivElement>>;
109
+ readonly Root: _$react.ForwardRefExoticComponent<Omit<CursorPaginationProps, "ref"> & _$react.RefAttributes<HTMLDivElement>>;
110
110
  /**
111
111
  * A pair of buttons for navigating between pages of data when using cursor-based pagination.
112
112
  *
@@ -122,7 +122,7 @@ declare const CursorPagination: {
122
122
  * />
123
123
  * ```
124
124
  */
125
- readonly Buttons: react.ForwardRefExoticComponent<Omit<CursorButtonsProps, "ref"> & react.RefAttributes<HTMLDivElement>>;
125
+ readonly Buttons: _$react.ForwardRefExoticComponent<Omit<CursorButtonsProps, "ref"> & _$react.RefAttributes<HTMLDivElement>>;
126
126
  /**
127
127
  * A select input for changing the number of items per page when using cursor-based pagination.
128
128
  *
@@ -136,7 +136,7 @@ declare const CursorPagination: {
136
136
  * />
137
137
  * ```
138
138
  */
139
- readonly PageSizeSelect: react.ForwardRefExoticComponent<Omit<CursorPageSizeSelectProps, "ref"> & react.RefAttributes<HTMLButtonElement>>;
139
+ readonly PageSizeSelect: _$react.ForwardRefExoticComponent<Omit<CursorPageSizeSelectProps, "ref"> & _$react.RefAttributes<HTMLButtonElement>>;
140
140
  /**
141
141
  * Displays the current page size when using cursor-based pagination as a read-only value.
142
142
  *
@@ -1,2 +1,2 @@
1
- import{t as e}from"./cx-D1HYnpvA.js";import{t}from"./slot-D_ZUrdEW.js";import{t as n}from"./icon-button-CeeHZOhh.js";import{t as r}from"./button-eAPtlsYO.js";import{n as i}from"./separator-fSV4z0Pq.js";import{t as a}from"./select-BXBu1jP_.js";import{createContext as o,forwardRef as s,useContext as c,useEffect as l,useState as u}from"react";import d from"tiny-invariant";import{jsx as f,jsxs as p}from"react/jsx-runtime";import{CaretLeftIcon as m}from"@phosphor-icons/react/CaretLeft";import{CaretRightIcon as h}from"@phosphor-icons/react/CaretRight";const g=o(void 0),_=s(({className:t,children:n,defaultPageSize:r,...i},a)=>{let[o,s]=u(r);return f(g.Provider,{value:{defaultPageSize:r,pageSize:o,setPageSize:s},children:f(`div`,{className:e(`inline-flex items-center justify-between gap-2`,t),ref:a,...i,children:n})})});_.displayName=`CursorPagination`;const v=s(({hasNextPage:e,hasPreviousPage:t,onNextPage:a,onPreviousPage:o,...s},c)=>p(r,{appearance:`panel`,ref:c,...s,children:[f(n,{appearance:`ghost`,disabled:!t,icon:f(m,{}),label:`Previous page`,onClick:o,size:`sm`,type:`button`}),f(i,{orientation:`vertical`,className:`min-h-5`}),f(n,{appearance:`ghost`,disabled:!e,icon:f(h,{}),label:`Next page`,onClick:a,size:`sm`,type:`button`})]}));v.displayName=`CursorButtons`;const y=[5,10,20,50,100],b=s(({className:t,pageSizes:n=y,onChangePageSize:r,...i},o)=>{let s=c(g);return d(s,`CursorPageSizeSelect must be used as a child of a CursorPagination component`),d(n.includes(s.defaultPageSize),`CursorPagination.defaultPageSize must be included in CursorPageSizeSelect.pageSizes`),d(n.includes(s.pageSize),`CursorPagination.pageSize must be included in CursorPageSizeSelect.pageSizes`),p(a.Root,{defaultValue:`${s.pageSize}`,onValueChange:e=>{let t=Number.parseInt(e,10);Number.isNaN(t)&&(t=s.defaultPageSize),s.setPageSize(t),r?.(t)},children:[f(a.Trigger,{ref:o,className:e(`w-auto min-w-36`,t),value:s.pageSize,...i,children:f(a.Value,{})}),f(a.Content,{width:`trigger`,children:n.map(e=>p(a.Item,{value:`${e}`,children:[e,` per page`]},e))})]})});b.displayName=`CursorPageSizeSelect`;function x({asChild:n=!1,className:r,...i}){let a=c(g);return d(a,`CursorPageSizeValue must be used as a child of a CursorPagination component`),p(n?t:`span`,{className:e(`text-muted text-sm font-normal`,r),...i,children:[a.pageSize,` per page`]})}x.displayName=`CursorPageSizeValue`;const S={Root:_,Buttons:v,PageSizeSelect:b,PageSizeValue:x};function C({listSize:e,pageSize:t}){let[n,r]=u(1),[i,a]=u(t);l(()=>{a(t),r(1)},[t]),l(()=>{r(1)},[e]);let o=Math.ceil(e/i),s=(n-1)*i,c=n>1,d=n<o;function f(e){r(Math.max(1,Math.min(e,o)))}function p(){d&&r(e=>Math.min(e+1,o))}function m(){c&&r(e=>Math.max(e-1,1))}function h(e){a(e),r(1)}function g(){r(o)}function _(){r(1)}return{currentPage:n,goToFirstPage:_,goToLastPage:g,goToPage:f,hasNextPage:d,hasPreviousPage:c,nextPage:p,offset:s,pageSize:i,previousPage:m,setPageSize:h,totalPages:o}}function w(e,t){return e.slice(t.offset,t.offset+t.pageSize)}export{S as CursorPagination,w as getOffsetPaginatedSlice,C as useOffsetPagination};
1
+ import{t as e}from"./cx-D1HYnpvA.js";import{t}from"./slot-D_ZUrdEW.js";import{t as n}from"./icon-button-CxxVPiKp.js";import{t as r}from"./button-eAPtlsYO.js";import{n as i}from"./separator-BuP5aENE.js";import{t as a}from"./select-Z13w6WBS.js";import{createContext as o,forwardRef as s,useContext as c,useEffect as l,useState as u}from"react";import d from"tiny-invariant";import{jsx as f,jsxs as p}from"react/jsx-runtime";import{CaretLeftIcon as m}from"@phosphor-icons/react/CaretLeft";import{CaretRightIcon as h}from"@phosphor-icons/react/CaretRight";const g=o(void 0),_=s(({className:t,children:n,defaultPageSize:r,...i},a)=>{let[o,s]=u(r);return f(g.Provider,{value:{defaultPageSize:r,pageSize:o,setPageSize:s},children:f(`div`,{className:e(`inline-flex items-center justify-between gap-2`,t),ref:a,...i,children:n})})});_.displayName=`CursorPagination`;const v=s(({hasNextPage:e,hasPreviousPage:t,onNextPage:a,onPreviousPage:o,...s},c)=>p(r,{appearance:`panel`,ref:c,...s,children:[f(n,{appearance:`ghost`,disabled:!t,icon:f(m,{}),label:`Previous page`,onClick:o,size:`sm`,type:`button`}),f(i,{orientation:`vertical`,className:`min-h-5`}),f(n,{appearance:`ghost`,disabled:!e,icon:f(h,{}),label:`Next page`,onClick:a,size:`sm`,type:`button`})]}));v.displayName=`CursorButtons`;const y=[5,10,20,50,100],b=s(({className:t,pageSizes:n=y,onChangePageSize:r,...i},o)=>{let s=c(g);return d(s,`CursorPageSizeSelect must be used as a child of a CursorPagination component`),d(n.includes(s.defaultPageSize),`CursorPagination.defaultPageSize must be included in CursorPageSizeSelect.pageSizes`),d(n.includes(s.pageSize),`CursorPagination.pageSize must be included in CursorPageSizeSelect.pageSizes`),p(a.Root,{defaultValue:`${s.pageSize}`,onValueChange:e=>{let t=Number.parseInt(e,10);Number.isNaN(t)&&(t=s.defaultPageSize),s.setPageSize(t),r?.(t)},children:[f(a.Trigger,{ref:o,className:e(`w-auto min-w-36`,t),value:s.pageSize,...i,children:f(a.Value,{})}),f(a.Content,{width:`trigger`,children:n.map(e=>p(a.Item,{value:`${e}`,children:[e,` per page`]},e))})]})});b.displayName=`CursorPageSizeSelect`;function x({asChild:n=!1,className:r,...i}){let a=c(g);return d(a,`CursorPageSizeValue must be used as a child of a CursorPagination component`),p(n?t:`span`,{className:e(`text-muted text-sm font-normal`,r),...i,children:[a.pageSize,` per page`]})}x.displayName=`CursorPageSizeValue`;const S={Root:_,Buttons:v,PageSizeSelect:b,PageSizeValue:x};function C({listSize:e,pageSize:t}){let[n,r]=u(1),[i,a]=u(t);l(()=>{a(t),r(1)},[t]),l(()=>{r(1)},[e]);let o=Math.ceil(e/i),s=(n-1)*i,c=n>1,d=n<o;function f(e){r(Math.max(1,Math.min(e,o)))}function p(){d&&r(e=>Math.min(e+1,o))}function m(){c&&r(e=>Math.max(e-1,1))}function h(e){a(e),r(1)}function g(){r(o)}function _(){r(1)}return{currentPage:n,goToFirstPage:_,goToLastPage:g,goToPage:f,hasNextPage:d,hasPreviousPage:c,nextPage:p,offset:s,pageSize:i,previousPage:m,setPageSize:h,totalPages:o}}function w(e,t){return e.slice(t.offset,t.offset+t.pageSize)}export{S as CursorPagination,w as getOffsetPaginatedSlice,C as useOffsetPagination};
2
2
  //# sourceMappingURL=pagination.js.map
package/dist/popover.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import * as react from "react";
1
+ import * as _$react from "react";
2
2
  import * as PopoverPrimitive from "@radix-ui/react-popover";
3
3
 
4
4
  //#region src/components/popover/popover.d.ts
@@ -39,7 +39,7 @@ declare const Popover: {
39
39
  * </Popover.Root>
40
40
  * ```
41
41
  */
42
- readonly Root: react.FC<PopoverPrimitive.PopoverProps>;
42
+ readonly Root: _$react.FC<PopoverPrimitive.PopoverProps>;
43
43
  /**
44
44
  * An optional element to position the PopoverContent against. If not used, content positions alongside the trigger.
45
45
  *
@@ -60,7 +60,7 @@ declare const Popover: {
60
60
  * </Popover.Root>
61
61
  * ```
62
62
  */
63
- readonly Anchor: react.ForwardRefExoticComponent<PopoverPrimitive.PopoverAnchorProps & react.RefAttributes<HTMLDivElement>>;
63
+ readonly Anchor: _$react.ForwardRefExoticComponent<PopoverPrimitive.PopoverAnchorProps & _$react.RefAttributes<HTMLDivElement>>;
64
64
  /**
65
65
  * A button that closes an open popover. Can be placed anywhere within the popover content.
66
66
  *
@@ -84,7 +84,7 @@ declare const Popover: {
84
84
  * </Popover.Root>
85
85
  * ```
86
86
  */
87
- readonly Close: react.ForwardRefExoticComponent<PopoverPrimitive.PopoverCloseProps & react.RefAttributes<HTMLButtonElement>>;
87
+ readonly Close: _$react.ForwardRefExoticComponent<PopoverPrimitive.PopoverCloseProps & _$react.RefAttributes<HTMLButtonElement>>;
88
88
  /**
89
89
  * The content to render inside the popover. Appears in a portal with rich styling and animations.
90
90
  *
@@ -106,7 +106,7 @@ declare const Popover: {
106
106
  * </Popover.Root>
107
107
  * ```
108
108
  */
109
- readonly Content: react.ForwardRefExoticComponent<Omit<PopoverPrimitive.PopoverContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & {
109
+ readonly Content: _$react.ForwardRefExoticComponent<Omit<PopoverPrimitive.PopoverContentProps & _$react.RefAttributes<HTMLDivElement>, "ref"> & {
110
110
  /**
111
111
  * The preferred width of the `PopoverContent` as a tailwind `max-w-` class.
112
112
  *
@@ -116,7 +116,7 @@ declare const Popover: {
116
116
  * @default `max-w-72`
117
117
  */
118
118
  preferredWidth?: `max-w-${string}`;
119
- } & react.RefAttributes<HTMLDivElement>>;
119
+ } & _$react.RefAttributes<HTMLDivElement>>;
120
120
  /**
121
121
  * The trigger button that opens the popover when clicked or focused.
122
122
  *
@@ -139,7 +139,7 @@ declare const Popover: {
139
139
  * </Popover.Root>
140
140
  * ```
141
141
  */
142
- readonly Trigger: react.ForwardRefExoticComponent<PopoverPrimitive.PopoverTriggerProps & react.RefAttributes<HTMLButtonElement>>;
142
+ readonly Trigger: _$react.ForwardRefExoticComponent<PopoverPrimitive.PopoverTriggerProps & _$react.RefAttributes<HTMLButtonElement>>;
143
143
  };
144
144
  //#endregion
145
145
  export { Popover };
@@ -1,9 +1,9 @@
1
1
  import { ComponentPropsWithoutRef } from "react";
2
- import * as react_jsx_runtime0 from "react/jsx-runtime";
2
+ import * as _$react_jsx_runtime0 from "react/jsx-runtime";
3
3
  import * as DialogPrimitive from "@radix-ui/react-dialog";
4
4
 
5
5
  //#region src/components/dialog/primitive.d.ts
6
- declare function Root(props: ComponentPropsWithoutRef<typeof DialogPrimitive.Root>): react_jsx_runtime0.JSX.Element;
6
+ declare function Root(props: ComponentPropsWithoutRef<typeof DialogPrimitive.Root>): _$react_jsx_runtime0.JSX.Element;
7
7
  declare namespace Root {
8
8
  var displayName: string;
9
9
  }
@@ -13,4 +13,4 @@ declare namespace Root {
13
13
  declare function isDialogOverlayTarget(target: EventTarget | null): boolean;
14
14
  //#endregion
15
15
  export { isDialogOverlayTarget as n, Root as t };
16
- //# sourceMappingURL=primitive-tuHqhoRE.d.ts.map
16
+ //# sourceMappingURL=primitive-BqLYh79k.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import { ComponentProps, HTMLAttributes } from "react";
2
- import * as react_jsx_runtime0 from "react/jsx-runtime";
2
+ import * as _$react_jsx_runtime0 from "react/jsx-runtime";
3
3
  import * as ProgressPrimitive from "@radix-ui/react-progress";
4
4
 
5
5
  //#region src/components/progress/types.d.ts
@@ -94,7 +94,7 @@ declare const ProgressDonut: {
94
94
  value: _value,
95
95
  indeterminateRotationSpeed,
96
96
  ...props
97
- }: Props): react_jsx_runtime0.JSX.Element;
97
+ }: Props): _$react_jsx_runtime0.JSX.Element;
98
98
  displayName: string;
99
99
  };
100
100
  /**
@@ -117,7 +117,7 @@ declare const ProgressDonut: {
117
117
  ({
118
118
  className,
119
119
  ...props
120
- }: ProgressDonutIndicatorProps): react_jsx_runtime0.JSX.Element;
120
+ }: ProgressDonutIndicatorProps): _$react_jsx_runtime0.JSX.Element;
121
121
  displayName: string;
122
122
  };
123
123
  };
@@ -172,7 +172,7 @@ declare function Root({
172
172
  max: _max,
173
173
  value: _value,
174
174
  ...props
175
- }: RootProps): react_jsx_runtime0.JSX.Element;
175
+ }: RootProps): _$react_jsx_runtime0.JSX.Element;
176
176
  declare namespace Root {
177
177
  var displayName: string;
178
178
  }
@@ -201,7 +201,7 @@ declare function Indicator({
201
201
  className,
202
202
  style,
203
203
  ...props
204
- }: IndicatorProps): react_jsx_runtime0.JSX.Element;
204
+ }: IndicatorProps): _$react_jsx_runtime0.JSX.Element;
205
205
  declare namespace Indicator {
206
206
  var displayName: string;
207
207
  }
@@ -1,7 +1,7 @@
1
- import { t as WithAsChild } from "./as-child-XMVTepJu.js";
2
- import * as react from "react";
1
+ import { t as WithAsChild } from "./as-child-CRRsxi3Y.js";
2
+ import * as _$react from "react";
3
3
  import { HTMLAttributes, ReactNode } from "react";
4
- import * as react_jsx_runtime0 from "react/jsx-runtime";
4
+ import * as _$react_jsx_runtime0 from "react/jsx-runtime";
5
5
  import { RadioGroupProps, RadioProps } from "@headlessui/react";
6
6
 
7
7
  //#region src/components/radio-group/radio-group.d.ts
@@ -56,9 +56,9 @@ declare const RadioGroup: {
56
56
  * </RadioGroup.Root>
57
57
  * ```
58
58
  */
59
- readonly Button: react.ForwardRefExoticComponent<Omit<RadioProps, "children"> & {
59
+ readonly Button: _$react.ForwardRefExoticComponent<Omit<RadioProps, "children"> & {
60
60
  children?: ReactNode | undefined;
61
- } & react.RefAttributes<HTMLDivElement>>;
61
+ } & _$react.RefAttributes<HTMLDivElement>>;
62
62
  /**
63
63
  * An inline group of radio buttons. Use RadioGroup.Button as direct children for horizontal radio layouts.
64
64
  *
@@ -76,9 +76,9 @@ declare const RadioGroup: {
76
76
  * </RadioGroup.Root>
77
77
  * ```
78
78
  */
79
- readonly ButtonGroup: react.ForwardRefExoticComponent<Omit<RadioGroupProps, "children" | "as"> & {
79
+ readonly ButtonGroup: _$react.ForwardRefExoticComponent<Omit<RadioGroupProps, "children" | "as"> & {
80
80
  children?: ReactNode | undefined;
81
- } & react.RefAttributes<HTMLElement>>;
81
+ } & _$react.RefAttributes<HTMLElement>>;
82
82
  /**
83
83
  * A radio card item with enhanced styling. Use it as a child of RadioGroup for card-based radio options.
84
84
  *
@@ -104,9 +104,9 @@ declare const RadioGroup: {
104
104
  * </RadioGroup.Root>
105
105
  * ```
106
106
  */
107
- readonly Card: react.ForwardRefExoticComponent<Omit<RadioProps, "children"> & {
107
+ readonly Card: _$react.ForwardRefExoticComponent<Omit<RadioProps, "children"> & {
108
108
  children?: ReactNode | undefined;
109
- } & react.RefAttributes<HTMLDivElement>>;
109
+ } & _$react.RefAttributes<HTMLDivElement>>;
110
110
  /**
111
111
  * The selection indicator for any radio item. Shows the checked state with customizable appearance.
112
112
  *
@@ -125,7 +125,7 @@ declare const RadioGroup: {
125
125
  children,
126
126
  className,
127
127
  ...props
128
- }: RadioIndicatorProps): react_jsx_runtime0.JSX.Element;
128
+ }: RadioIndicatorProps): _$react_jsx_runtime0.JSX.Element;
129
129
  displayName: string;
130
130
  };
131
131
  /**
@@ -154,7 +154,7 @@ declare const RadioGroup: {
154
154
  onClick,
155
155
  onKeyDown,
156
156
  ...props
157
- }: RadioInputSandboxProps): react_jsx_runtime0.JSX.Element;
157
+ }: RadioInputSandboxProps): _$react_jsx_runtime0.JSX.Element;
158
158
  displayName: string;
159
159
  };
160
160
  /**
@@ -170,9 +170,9 @@ declare const RadioGroup: {
170
170
  * </RadioGroup.Item>
171
171
  * ```
172
172
  */
173
- readonly Item: react.ForwardRefExoticComponent<Omit<RadioProps, "children"> & {
173
+ readonly Item: _$react.ForwardRefExoticComponent<Omit<RadioProps, "children"> & {
174
174
  children?: ReactNode | undefined;
175
- } & react.RefAttributes<HTMLDivElement>>;
175
+ } & _$react.RefAttributes<HTMLDivElement>>;
176
176
  /**
177
177
  * The content wrapper for any radio item. Use it to wrap labels, descriptions, or content of a radio item.
178
178
  *
@@ -197,7 +197,7 @@ declare const RadioGroup: {
197
197
  children,
198
198
  className,
199
199
  ...props
200
- }: RadioItemContentProps): react_jsx_runtime0.JSX.Element;
200
+ }: RadioItemContentProps): _$react_jsx_runtime0.JSX.Element;
201
201
  displayName: string;
202
202
  };
203
203
  /**
@@ -223,9 +223,9 @@ declare const RadioGroup: {
223
223
  * </RadioGroup.Root>
224
224
  * ```
225
225
  */
226
- readonly List: react.ForwardRefExoticComponent<Omit<RadioGroupProps, "children" | "as"> & {
226
+ readonly List: _$react.ForwardRefExoticComponent<Omit<RadioGroupProps, "children" | "as"> & {
227
227
  children?: ReactNode | undefined;
228
- } & react.RefAttributes<HTMLElement>>;
228
+ } & _$react.RefAttributes<HTMLElement>>;
229
229
  /**
230
230
  * A radio list item that is used inside a RadioGroup.List for connected list-style radio options.
231
231
  *
@@ -251,9 +251,9 @@ declare const RadioGroup: {
251
251
  * </RadioGroup.Root>
252
252
  * ```
253
253
  */
254
- readonly ListItem: react.ForwardRefExoticComponent<Omit<RadioProps, "children"> & {
254
+ readonly ListItem: _$react.ForwardRefExoticComponent<Omit<RadioProps, "children"> & {
255
255
  children?: ReactNode | undefined;
256
- } & react.RefAttributes<HTMLDivElement>>;
256
+ } & _$react.RefAttributes<HTMLDivElement>>;
257
257
  /**
258
258
  * The root radio group component. Manages the state of the children radios where only one can be selected.
259
259
  *
@@ -269,9 +269,9 @@ declare const RadioGroup: {
269
269
  * </RadioGroup.Root>
270
270
  * ```
271
271
  */
272
- readonly Root: react.ForwardRefExoticComponent<Omit<RadioGroupProps, "children" | "as"> & {
272
+ readonly Root: _$react.ForwardRefExoticComponent<Omit<RadioGroupProps, "children" | "as"> & {
273
273
  children?: ReactNode | undefined;
274
- } & react.RefAttributes<HTMLElement>>;
274
+ } & _$react.RefAttributes<HTMLElement>>;
275
275
  };
276
276
  //#endregion
277
277
  export { RadioGroup };
@@ -1,2 +1,2 @@
1
- import{t as e}from"./cx-D1HYnpvA.js";import{t}from"./slot-D_ZUrdEW.js";import{t as n}from"./is-input-BFR8yMM7.js";import{Children as r,cloneElement as i,createContext as a,forwardRef as o,isValidElement as s,useContext as c,useRef as l}from"react";import u from"clsx";import{Fragment as d,jsx as f}from"react/jsx-runtime";import{Radio as p,RadioGroup as m}from"@headlessui/react";const h=o((e,t)=>f(m,{...e,ref:t}));h.displayName=`RadioGroup`;const g=a({autofocus:!1,checked:!1,disabled:!1,focus:!1,hover:!1}),_=o(({children:t,className:n,...r},i)=>f(p,{className:e(`group/radio cursor-pointer aria-disabled:cursor-default [&_label]:cursor-inherit flex gap-2 py-1 text-sm focus:outline-hidden`,n),as:`div`,...r,ref:i,children:e=>f(g.Provider,{value:e,children:t})}));_.displayName=`RadioItem`;const v=({checked:t,disabled:n,focus:r,hover:i})=>f(`span`,{className:e(`border-form flex size-4 items-center justify-center rounded-full border shrink-0`,n&&`cursor-default opacity-50`,t&&`border-accent-500 bg-accent-500`,r&&!n&&`border-accent-600 ring-focus-accent ring-4`,i&&`border-accent-600`),children:t&&f(`span`,{className:`size-2 rounded-full bg-[#fff] shrink-0`})}),y=({children:t,className:n,...r})=>{let i=c(g);return f(`div`,{className:e(`radio-indicator inline-flex size-5 select-none items-center justify-center shrink-0`,n),...r,children:t==null?f(v,{...i}):typeof t==`function`?t(i):t})};y.displayName=`RadioIndicator`;const b=o(({className:e,...t},n)=>f(h,{className:u(`-space-y-px`,e),...t,ref:n}));b.displayName=`RadioGroupList`;const x=o(({children:t,className:n,...r},i)=>f(p,{as:`div`,className:e(`group/radio border-form [&_label]:cursor-inherit relative flex select-none gap-2 border px-3 py-2 text-sm`,`cursor-pointer aria-disabled:cursor-default focus:outline-hidden`,`focus-visible:ring-focus-accent not-aria-disabled:focus-visible:border-accent-600 focus-visible:ring-4`,`first-of-type:rounded-tl-md first-of-type:rounded-tr-md last-of-type:rounded-bl-md last-of-type:rounded-br-md`,`aria-disabled:border-form/50 not-aria-disabled:hover:z-1 not-aria-disabled:hover:border-accent-600`,`aria-checked:z-1 aria-checked:border-accent-500/40 aria-checked:bg-accent-500/10 dark-high-contrast:aria-checked:border-accent-400 high-contrast:aria-checked:border-accent-400 not-aria-disabled:hover:aria-checked:border-accent-600`,`has-[.radio-indicator:first-child]:pl-2 has-[.radio-indicator:last-child]:pr-2`,n),ref:i,...r,children:e=>f(d,{children:f(g.Provider,{value:e,children:t})})}));x.displayName=`RadioListItem`;const S=o(({children:e,className:t,...n},r)=>f(p,{as:`div`,className:u(`group/radio border-card bg-card [&_label]:cursor-inherit relative rounded-md border p-4 text-sm`,`cursor-pointer aria-disabled:cursor-default focus:outline-hidden`,`focus-visible:ring-focus-accent not-aria-disabled:focus-visible:border-accent-600 focus-visible:ring-4`,`first-of-type:rounded-tl-md first-of-type:rounded-tr-md last-of-type:rounded-bl-md last-of-type:rounded-br-md`,`aria-disabled:border-form/50 not-aria-disabled:hover:z-1 not-aria-disabled:hover:border-accent-600`,`aria-checked:z-1 aria-checked:border-accent-500/40 aria-checked:bg-accent-500/10 not-aria-disabled:hover:aria-checked:border-accent-600 dark-high-contrast:aria-checked:border-accent-400 high-contrast:aria-checked:border-accent-400`,t),...n,ref:r,children:t=>f(d,{children:f(g.Provider,{value:t,children:e})})}));S.displayName=`RadioCard`;const C=({asChild:e=!1,children:n,className:r,...i})=>{let a=c(g);return f(e?t:`div`,{className:u(`min-w-0 flex-1`,a.disabled&&`opacity-50`,r),...i,children:n})};C.displayName=`RadioItemContent`;const w=o(({className:e,...t},n)=>f(h,{className:u(`flex flex-row flex-nowrap -space-x-px`,e),...t,ref:n}));w.displayName=`RadioButtonGroup`;const T=o(({children:t,className:n,...r},i)=>f(p,{as:`div`,className:e(`group/radio border-form [&_label]:cursor-inherit relative flex flex-1 select-none items-center justify-center gap-2 border px-3 text-sm`,`h-9`,`focus-visible:ring-focus-accent not-aria-disabled:focus-visible:border-accent-600 focus-visible:ring-4`,`cursor-pointer aria-disabled:cursor-default focus:outline-hidden`,`first-of-type:rounded-bl-md first-of-type:rounded-tl-md last-of-type:rounded-br-md last-of-type:rounded-tr-md`,`not-aria-disabled:hover:z-1 not-aria-disabled:hover:border-accent-600 aria-disabled:opacity-50`,`aria-checked:z-1 aria-checked:border-accent-500/40 aria-checked:bg-accent-500/10 not-aria-disabled:hover:aria-checked:border-accent-600`,`has-[.radio-indicator:first-child]:pl-2 has-[.radio-indicator:last-child]:pr-2`,n),ref:i,...r,children:e=>f(d,{children:f(g.Provider,{value:e,children:t})})}));T.displayName=`RadioButton`;const E=({children:e,onClick:t,onKeyDown:a,...o})=>{let u=l(null),d=c(g),p=r.only(e),m=d.disabled||!d.checked;return f(`div`,{role:`none`,ref:u,onKeyDown:e=>{if(d.disabled){e.stopPropagation(),e.preventDefault();return}switch(e.key){case`Enter`:case`Tab`:break;default:e.stopPropagation()}a?.(e)},onClick:e=>{if(d.disabled){e.stopPropagation(),e.preventDefault();return}let r=e.target;n(r)&&window.requestAnimationFrame(()=>{r.focus()}),t?.(e)},...o,children:s(p)?i(p,{disabled:d.disabled||p.props.disabled,tabIndex:m?-1:p.props.tabIndex}):null})};E.displayName=`RadioInputSandbox`;const D={Button:T,ButtonGroup:w,Card:S,Indicator:y,InputSandbox:E,Item:_,ItemContent:C,List:b,ListItem:x,Root:h};export{D as RadioGroup};
1
+ import{t as e}from"./cx-D1HYnpvA.js";import{t}from"./slot-D_ZUrdEW.js";import{t as n}from"./is-input-CC_n6EGM.js";import{Children as r,cloneElement as i,createContext as a,forwardRef as o,isValidElement as s,useContext as c,useRef as l}from"react";import u from"clsx";import{Fragment as d,jsx as f}from"react/jsx-runtime";import{Radio as p,RadioGroup as m}from"@headlessui/react";const h=o((e,t)=>f(m,{...e,ref:t}));h.displayName=`RadioGroup`;const g=a({autofocus:!1,checked:!1,disabled:!1,focus:!1,hover:!1}),_=o(({children:t,className:n,...r},i)=>f(p,{className:e(`group/radio cursor-pointer aria-disabled:cursor-default [&_label]:cursor-inherit flex gap-2 py-1 text-sm focus:outline-hidden`,n),as:`div`,...r,ref:i,children:e=>f(g.Provider,{value:e,children:t})}));_.displayName=`RadioItem`;const v=({checked:t,disabled:n,focus:r,hover:i})=>f(`span`,{className:e(`border-form flex size-4 items-center justify-center rounded-full border shrink-0`,n&&`cursor-default opacity-50`,t&&`border-accent-600 bg-accent-600`,r&&!n&&`border-accent-600 ring-focus-accent ring-4`,i&&`border-accent-600`),children:t&&f(`span`,{className:`size-2 rounded-full bg-white shrink-0`})}),y=({children:t,className:n,...r})=>{let i=c(g);return f(`div`,{className:e(`radio-indicator inline-flex size-5 select-none items-center justify-center shrink-0`,n),...r,children:t==null?f(v,{...i}):typeof t==`function`?t(i):t})};y.displayName=`RadioIndicator`;const b=o(({className:e,...t},n)=>f(h,{className:u(`-space-y-px`,e),...t,ref:n}));b.displayName=`RadioGroupList`;const x=o(({children:t,className:n,...r},i)=>f(p,{as:`div`,className:e(`group/radio border-form [&_label]:cursor-inherit relative flex select-none gap-2 border px-3 py-2 text-sm`,`cursor-pointer aria-disabled:cursor-default focus:outline-hidden`,`focus-visible:ring-focus-accent not-aria-disabled:focus-visible:border-accent-600 focus-visible:ring-4`,`first-of-type:rounded-tl-md first-of-type:rounded-tr-md last-of-type:rounded-bl-md last-of-type:rounded-br-md`,`aria-disabled:border-form/50 not-aria-disabled:hover:z-1 not-aria-disabled:hover:border-accent-600`,`aria-checked:z-1 aria-checked:border-accent-500/40 aria-checked:bg-accent-500/10 dark-high-contrast:aria-checked:border-accent-400 high-contrast:aria-checked:border-accent-400 not-aria-disabled:hover:aria-checked:border-accent-600`,`has-[.radio-indicator:first-child]:pl-2 has-[.radio-indicator:last-child]:pr-2`,n),ref:i,...r,children:e=>f(d,{children:f(g.Provider,{value:e,children:t})})}));x.displayName=`RadioListItem`;const S=o(({children:e,className:t,...n},r)=>f(p,{as:`div`,className:u(`group/radio border-card bg-card [&_label]:cursor-inherit relative rounded-md border p-4 text-sm`,`cursor-pointer aria-disabled:cursor-default focus:outline-hidden`,`focus-visible:ring-focus-accent not-aria-disabled:focus-visible:border-accent-600 focus-visible:ring-4`,`first-of-type:rounded-tl-md first-of-type:rounded-tr-md last-of-type:rounded-bl-md last-of-type:rounded-br-md`,`aria-disabled:border-form/50 not-aria-disabled:hover:z-1 not-aria-disabled:hover:border-accent-600`,`aria-checked:z-1 aria-checked:border-accent-600/50 aria-checked:bg-accent-500/10 not-aria-disabled:hover:aria-checked:border-accent-600 dark-high-contrast:aria-checked:border-accent-600 high-contrast:aria-checked:border-accent-600`,t),...n,ref:r,children:t=>f(d,{children:f(g.Provider,{value:t,children:e})})}));S.displayName=`RadioCard`;const C=({asChild:e=!1,children:n,className:r,...i})=>{let a=c(g);return f(e?t:`div`,{className:u(`min-w-0 flex-1`,a.disabled&&`opacity-50`,r),...i,children:n})};C.displayName=`RadioItemContent`;const w=o(({className:e,...t},n)=>f(h,{className:u(`flex flex-row flex-nowrap -space-x-px`,e),...t,ref:n}));w.displayName=`RadioButtonGroup`;const T=o(({children:t,className:n,...r},i)=>f(p,{as:`div`,className:e(`group/radio border-form [&_label]:cursor-inherit relative flex flex-1 select-none items-center justify-center gap-2 border px-3 text-sm`,`h-9`,`focus-visible:ring-focus-accent not-aria-disabled:focus-visible:border-accent-600 focus-visible:ring-4`,`cursor-pointer aria-disabled:cursor-default focus:outline-hidden`,`first-of-type:rounded-bl-md first-of-type:rounded-tl-md last-of-type:rounded-br-md last-of-type:rounded-tr-md`,`not-aria-disabled:hover:z-1 not-aria-disabled:hover:border-accent-600 aria-disabled:opacity-50`,`aria-checked:z-1 aria-checked:border-accent-600/40 aria-checked:bg-accent-500/10 not-aria-disabled:hover:aria-checked:border-accent-600`,`has-[.radio-indicator:first-child]:pl-2 has-[.radio-indicator:last-child]:pr-2`,n),ref:i,...r,children:e=>f(d,{children:f(g.Provider,{value:e,children:t})})}));T.displayName=`RadioButton`;const E=({children:e,onClick:t,onKeyDown:a,...o})=>{let u=l(null),d=c(g),p=r.only(e),m=d.disabled||!d.checked;return f(`div`,{role:`none`,ref:u,onKeyDown:e=>{if(d.disabled){e.stopPropagation(),e.preventDefault();return}switch(e.key){case`Enter`:case`Tab`:break;default:e.stopPropagation()}a?.(e)},onClick:e=>{if(d.disabled){e.stopPropagation(),e.preventDefault();return}let r=e.target;n(r)&&window.requestAnimationFrame(()=>{r.focus()}),t?.(e)},...o,children:s(p)?i(p,{disabled:d.disabled||p.props.disabled,tabIndex:m?-1:p.props.tabIndex}):null})};E.displayName=`RadioInputSandbox`;const D={Button:T,ButtonGroup:w,Card:S,Indicator:y,InputSandbox:E,Item:_,ItemContent:C,List:b,ListItem:x,Root:h};export{D as RadioGroup};
2
2
  //# sourceMappingURL=radio-group.js.map