@ngrok/mantle 0.73.3 → 0.73.4

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 (261) hide show
  1. package/dist/accordion.d.ts +7 -9
  2. package/dist/accordion.js +1 -1
  3. package/dist/accordion.js.map +1 -1
  4. package/dist/agent.json +1 -1
  5. package/dist/alert-dialog.d.ts +33 -38
  6. package/dist/alert-dialog.js +1 -1
  7. package/dist/alert-dialog.js.map +1 -1
  8. package/dist/alert.d.ts +9 -11
  9. package/dist/alert.js +1 -1
  10. package/dist/alert.js.map +1 -1
  11. package/dist/{anchor-2stEauOz.js → anchor-CcTY5SIz.js} +2 -2
  12. package/dist/{anchor-2stEauOz.js.map → anchor-CcTY5SIz.js.map} +1 -1
  13. package/dist/anchor.d.ts +2 -3
  14. package/dist/anchor.js +1 -1
  15. package/dist/{as-child-CpZKMqTE.d.ts → as-child-uN_018tj.d.ts} +1 -1
  16. package/dist/badge.d.ts +3 -4
  17. package/dist/badge.js +1 -1
  18. package/dist/badge.js.map +1 -1
  19. package/dist/{booleanish-CBGdPL3Q.js → booleanish-BfvnW6vy.js} +1 -1
  20. package/dist/{booleanish-CBGdPL3Q.js.map → booleanish-BfvnW6vy.js.map} +1 -1
  21. package/dist/{browser-only-QPyyfLaB.js → browser-only-BSl_hruR.js} +1 -1
  22. package/dist/{browser-only-QPyyfLaB.js.map → browser-only-BSl_hruR.js.map} +1 -1
  23. package/dist/browser-only.js +1 -1
  24. package/dist/{button-POMJ-20y.js → button-BAxneEMu.js} +2 -2
  25. package/dist/{button-POMJ-20y.js.map → button-BAxneEMu.js.map} +1 -1
  26. package/dist/{button-DbHFERMB.d.ts → button-BYZOBUgj.d.ts} +16 -19
  27. package/dist/{button-GokecthL.js → button-uMIZVKit.js} +2 -2
  28. package/dist/{button-GokecthL.js.map → button-uMIZVKit.js.map} +1 -1
  29. package/dist/button.d.ts +4 -4
  30. package/dist/button.js +1 -1
  31. package/dist/calendar.d.ts +1 -2
  32. package/dist/calendar.js +1 -1
  33. package/dist/calendar.js.map +1 -1
  34. package/dist/card.d.ts +6 -7
  35. package/dist/card.js +1 -1
  36. package/dist/card.js.map +1 -1
  37. package/dist/checkbox.d.ts +3 -4
  38. package/dist/checkbox.js +1 -1
  39. package/dist/checkbox.js.map +1 -1
  40. package/dist/code-block.d.ts +17 -19
  41. package/dist/code-block.js +1 -1
  42. package/dist/code-block.js.map +1 -1
  43. package/dist/code-block_highlight-utils.d.ts +1 -1
  44. package/dist/code-block_highlight-utils.js +1 -1
  45. package/dist/code.d.ts +2 -3
  46. package/dist/code.js +1 -1
  47. package/dist/code.js.map +1 -1
  48. package/dist/color.d.ts +2 -2
  49. package/dist/color.js.map +1 -1
  50. package/dist/combobox.d.ts +11 -13
  51. package/dist/combobox.js +1 -1
  52. package/dist/combobox.js.map +1 -1
  53. package/dist/command.d.ts +133 -220
  54. package/dist/command.js +1 -1
  55. package/dist/command.js.map +1 -1
  56. package/dist/{compose-refs-DZ3cPi47.js → compose-refs-Cjf2gfB8.js} +1 -1
  57. package/dist/{compose-refs-DZ3cPi47.js.map → compose-refs-Cjf2gfB8.js.map} +1 -1
  58. package/dist/{copy-to-clipboard-CNMRyck4.js → copy-to-clipboard-Baw30q9O.js} +2 -2
  59. package/dist/{copy-to-clipboard-CNMRyck4.js.map → copy-to-clipboard-Baw30q9O.js.map} +1 -1
  60. package/dist/{cx-D1HYnpvA.js → cx-CBSnSC36.js} +1 -1
  61. package/dist/{cx-D1HYnpvA.js.map → cx-CBSnSC36.js.map} +1 -1
  62. package/dist/cx.js +1 -1
  63. package/dist/data-table.d.ts +13 -15
  64. package/dist/data-table.js +1 -1
  65. package/dist/data-table.js.map +1 -1
  66. package/dist/{deep-non-nullable-Xu7ckQM6.d.ts → deep-non-nullable-BxRoySYR.d.ts} +1 -1
  67. package/dist/description-list.d.ts +5 -6
  68. package/dist/description-list.js +1 -1
  69. package/dist/description-list.js.map +1 -1
  70. package/dist/{dialog-B1KCB7JT.js → dialog-Dn-brQBw.js} +2 -2
  71. package/dist/{dialog-B1KCB7JT.js.map → dialog-Dn-brQBw.js.map} +1 -1
  72. package/dist/dialog.d.ts +14 -17
  73. package/dist/dialog.js +1 -1
  74. package/dist/{direction-D9IZ1wW6.d.ts → direction-CcTY0FmA.d.ts} +2 -2
  75. package/dist/{direction-HqPHXGIs.js → direction-Wa9W2F61.js} +1 -1
  76. package/dist/{direction-HqPHXGIs.js.map → direction-Wa9W2F61.js.map} +1 -1
  77. package/dist/{dropdown-menu-CvOiQUSZ.d.ts → dropdown-menu-BgYk4L8o.d.ts} +22 -24
  78. package/dist/{dropdown-menu-DY4w933w.js → dropdown-menu-C3YZJBkV.js} +2 -2
  79. package/dist/{dropdown-menu-DY4w933w.js.map → dropdown-menu-C3YZJBkV.js.map} +1 -1
  80. package/dist/dropdown-menu.d.ts +1 -1
  81. package/dist/dropdown-menu.js +1 -1
  82. package/dist/empty.d.ts +7 -8
  83. package/dist/empty.js +1 -1
  84. package/dist/empty.js.map +1 -1
  85. package/dist/{field-context-B7Z1cmZW.js → field-context-4k1kI7Bo.js} +2 -2
  86. package/dist/{field-context-B7Z1cmZW.js.map → field-context-4k1kI7Bo.js.map} +1 -1
  87. package/dist/field.d.ts +23 -25
  88. package/dist/field.js +1 -1
  89. package/dist/field.js.map +1 -1
  90. package/dist/flag.d.ts +1 -2
  91. package/dist/flag.js +1 -1
  92. package/dist/flag.js.map +1 -1
  93. package/dist/hooks.d.ts +3 -3
  94. package/dist/hooks.js +1 -1
  95. package/dist/hooks.js.map +1 -1
  96. package/dist/hover-card.d.ts +4 -6
  97. package/dist/hover-card.js +1 -1
  98. package/dist/hover-card.js.map +1 -1
  99. package/dist/{icon-bWc5yC3-.js → icon-C8bYBIHW.js} +2 -2
  100. package/dist/{icon-bWc5yC3-.js.map → icon-C8bYBIHW.js.map} +1 -1
  101. package/dist/{icon-button-ZKN0sRIJ.js → icon-button-C_Ht_g1C.js} +2 -2
  102. package/dist/{icon-button-ZKN0sRIJ.js.map → icon-button-C_Ht_g1C.js.map} +1 -1
  103. package/dist/{icon-button-BDTb-lxs.d.ts → icon-button-ntupABbM.d.ts} +6 -8
  104. package/dist/{icon-BJ7q2RXZ.d.ts → icon-n49kOh4_.d.ts} +3 -4
  105. package/dist/icon.d.ts +3 -3
  106. package/dist/icon.js +1 -1
  107. package/dist/icons.d.ts +9 -10
  108. package/dist/icons.js +1 -1
  109. package/dist/icons.js.map +1 -1
  110. package/dist/{in-view-BUgyu-Tk.d.ts → in-view-BC3wmz-a.d.ts} +1 -1
  111. package/dist/{in-view-CeVqeGbv.js → in-view-C2DpZ6s0.js} +1 -1
  112. package/dist/{in-view-CeVqeGbv.js.map → in-view-C2DpZ6s0.js.map} +1 -1
  113. package/dist/{index-BhlxYL_y.d.ts → index-BL5WVva_.d.ts} +3 -6
  114. package/dist/{index-CWXKBva-.d.ts → index-DBZ3eRsl.d.ts} +5 -7
  115. package/dist/{index-DS_4n2eb.d.ts → index-DorCusfG.d.ts} +1 -1
  116. package/dist/{index-BbZBDzPh.d.ts → index-L3NmbHi5.d.ts} +1 -1
  117. package/dist/input.d.ts +7 -8
  118. package/dist/input.js +1 -1
  119. package/dist/input.js.map +1 -1
  120. package/dist/{is-input-CtUHJGgL.js → is-input-CXmS0OFN.js} +1 -1
  121. package/dist/{is-input-CtUHJGgL.js.map → is-input-CXmS0OFN.js.map} +1 -1
  122. package/dist/{kbd-CbMxDL9E.js → kbd-Bv6tefdB.js} +2 -2
  123. package/dist/{kbd-CbMxDL9E.js.map → kbd-Bv6tefdB.js.map} +1 -1
  124. package/dist/kbd.d.ts +1 -2
  125. package/dist/kbd.js +1 -1
  126. package/dist/{label-x6FcOpxc.js → label-DhIUmTN2.js} +2 -2
  127. package/dist/{label-x6FcOpxc.js.map → label-DhIUmTN2.js.map} +1 -1
  128. package/dist/label.d.ts +2 -4
  129. package/dist/label.js +1 -1
  130. package/dist/llms.txt +1 -1
  131. package/dist/main.d.ts +1 -2
  132. package/dist/main.js +1 -1
  133. package/dist/main.js.map +1 -1
  134. package/dist/media-object.d.ts +4 -5
  135. package/dist/media-object.js +1 -1
  136. package/dist/media-object.js.map +1 -1
  137. package/dist/multi-select.d.ts +16 -18
  138. package/dist/multi-select.js +1 -1
  139. package/dist/multi-select.js.map +1 -1
  140. package/dist/otp-input.d.ts +6 -7
  141. package/dist/otp-input.js +1 -1
  142. package/dist/otp-input.js.map +1 -1
  143. package/dist/pagination.d.ts +7 -9
  144. package/dist/pagination.js +1 -1
  145. package/dist/pagination.js.map +1 -1
  146. package/dist/{popover-CoZxokw_.js → popover-DponNBot.js} +2 -2
  147. package/dist/{popover-CoZxokw_.js.map → popover-DponNBot.js.map} +1 -1
  148. package/dist/popover.d.ts +6 -7
  149. package/dist/popover.js +1 -1
  150. package/dist/primitive-Cn3h4DJg.js +2 -0
  151. package/dist/primitive-Cn3h4DJg.js.map +1 -0
  152. package/dist/{primitive-qkxTYBUY.d.ts → primitive-D_-h74Kt.d.ts} +2 -3
  153. package/dist/progress.d.ts +4 -5
  154. package/dist/progress.js +1 -1
  155. package/dist/progress.js.map +1 -1
  156. package/dist/radio-group.d.ts +18 -20
  157. package/dist/radio-group.js +1 -1
  158. package/dist/radio-group.js.map +1 -1
  159. package/dist/{resolve-pre-rendered-props-BfWe69-w.js → resolve-pre-rendered-props-C-vrNxH1.js} +8 -8
  160. package/dist/resolve-pre-rendered-props-C-vrNxH1.js.map +1 -0
  161. package/dist/{resolve-pre-rendered-props-BONSCwYA.d.ts → resolve-pre-rendered-props-DxJ9-DAl.d.ts} +1 -1
  162. package/dist/sandboxed-on-click.d.ts +3 -4
  163. package/dist/sandboxed-on-click.js +1 -1
  164. package/dist/sandboxed-on-click.js.map +1 -1
  165. package/dist/{select-SZFFzYs0.d.ts → select-C15-XvRT.d.ts} +15 -16
  166. package/dist/select-Cxc9VmP8.js +2 -0
  167. package/dist/select-Cxc9VmP8.js.map +1 -0
  168. package/dist/select.d.ts +1 -1
  169. package/dist/select.js +1 -1
  170. package/dist/separator-Bqjy77rG.js +2 -0
  171. package/dist/separator-Bqjy77rG.js.map +1 -0
  172. package/dist/separator.d.ts +3 -5
  173. package/dist/separator.js +1 -1
  174. package/dist/sheet.d.ts +15 -19
  175. package/dist/sheet.js +1 -1
  176. package/dist/sheet.js.map +1 -1
  177. package/dist/skeleton.d.ts +4 -6
  178. package/dist/skeleton.js +1 -1
  179. package/dist/skeleton.js.map +1 -1
  180. package/dist/skip-to-main-link.d.ts +1 -2
  181. package/dist/skip-to-main-link.js +1 -1
  182. package/dist/skip-to-main-link.js.map +1 -1
  183. package/dist/slider.d.ts +1 -2
  184. package/dist/slider.js +1 -1
  185. package/dist/slider.js.map +1 -1
  186. package/dist/{slot-D_ZUrdEW.js → slot-CV5fmqFr.js} +2 -2
  187. package/dist/{slot-D_ZUrdEW.js.map → slot-CV5fmqFr.js.map} +1 -1
  188. package/dist/slot.d.ts +1 -1
  189. package/dist/slot.js +1 -1
  190. package/dist/{sort-mXo37xN2.js → sort-BPX2Fk9t.js} +2 -2
  191. package/dist/{sort-mXo37xN2.js.map → sort-BPX2Fk9t.js.map} +1 -1
  192. package/dist/split-button.d.ts +10 -12
  193. package/dist/split-button.js +1 -1
  194. package/dist/split-button.js.map +1 -1
  195. package/dist/{svg-only-7gYlsX8f.js → svg-only-Cz1cby8y.js} +2 -2
  196. package/dist/{svg-only-7gYlsX8f.js.map → svg-only-Cz1cby8y.js.map} +1 -1
  197. package/dist/{svg-only-D4uqM1OC.d.ts → svg-only-f6ToFLH0.d.ts} +3 -4
  198. package/dist/switch.d.ts +3 -5
  199. package/dist/switch.js +1 -1
  200. package/dist/switch.js.map +1 -1
  201. package/dist/{table-CjSQkfZe.d.ts → table-BWD9IlIN.d.ts} +10 -12
  202. package/dist/{table-CHd39aT-.js → table-eyoUW2Uv.js} +2 -2
  203. package/dist/{table-CHd39aT-.js.map → table-eyoUW2Uv.js.map} +1 -1
  204. package/dist/table.d.ts +1 -1
  205. package/dist/table.js +1 -1
  206. package/dist/tabs.d.ts +6 -9
  207. package/dist/tabs.js +1 -1
  208. package/dist/tabs.js.map +1 -1
  209. package/dist/text-area.d.ts +2 -3
  210. package/dist/text-area.js +1 -1
  211. package/dist/text-area.js.map +1 -1
  212. package/dist/theme-provider-MMwxHEfw.js +2 -0
  213. package/dist/theme-provider-MMwxHEfw.js.map +1 -0
  214. package/dist/theme.d.ts +9 -10
  215. package/dist/theme.js +1 -1
  216. package/dist/theme.js.map +1 -1
  217. package/dist/{themes-FPux5kIu.d.ts → themes-CYNpplwN.d.ts} +1 -1
  218. package/dist/toast-CR3MVChj.js +2 -0
  219. package/dist/toast-CR3MVChj.js.map +1 -0
  220. package/dist/toast.d.ts +8 -10
  221. package/dist/toast.js +1 -1
  222. package/dist/tooltip.d.ts +4 -6
  223. package/dist/tooltip.js +1 -1
  224. package/dist/tooltip.js.map +1 -1
  225. package/dist/{traffic-policy-file-BwHHdhWJ.js → traffic-policy-file-0g5RXFqu.js} +1 -1
  226. package/dist/{traffic-policy-file-BwHHdhWJ.js.map → traffic-policy-file-0g5RXFqu.js.map} +1 -1
  227. package/dist/{types-QKZ5fvaQ.d.ts → types-BvUzforF.d.ts} +1 -1
  228. package/dist/types-D85fCNV3.js +2 -0
  229. package/dist/{types-884RJJqm.js.map → types-D85fCNV3.js.map} +1 -1
  230. package/dist/types.d.ts +6 -6
  231. package/dist/types.js +1 -1
  232. package/dist/use-copy-to-clipboard-BLpquU9d.js +2 -0
  233. package/dist/{use-copy-to-clipboard-CTgtLjUg.js.map → use-copy-to-clipboard-BLpquU9d.js.map} +1 -1
  234. package/dist/{use-isomorphic-layout-effect-CNSD0lhi.js → use-isomorphic-layout-effect-DdTRtMY-.js} +1 -1
  235. package/dist/{use-isomorphic-layout-effect-CNSD0lhi.js.map → use-isomorphic-layout-effect-DdTRtMY-.js.map} +1 -1
  236. package/dist/{use-matches-media-query-CojcYxlA.js → use-matches-media-query-CMSxHR9n.js} +1 -1
  237. package/dist/{use-matches-media-query-CojcYxlA.js.map → use-matches-media-query-CMSxHR9n.js.map} +1 -1
  238. package/dist/{use-prefers-reduced-motion-Bpx8G3UT.js → use-prefers-reduced-motion-CWIoFA6W.js} +2 -2
  239. package/dist/{use-prefers-reduced-motion-Bpx8G3UT.js.map → use-prefers-reduced-motion-CWIoFA6W.js.map} +1 -1
  240. package/dist/utils.d.ts +2 -2
  241. package/dist/utils.js +1 -1
  242. package/dist/utils.js.map +1 -1
  243. package/dist/{validation-BYME8rWN.js → validation-DCyx-ceH.js} +1 -1
  244. package/dist/{validation-BYME8rWN.js.map → validation-DCyx-ceH.js.map} +1 -1
  245. package/dist/{validation-CBSOmooP.d.ts → validation-xyX_6kph.d.ts} +1 -1
  246. package/dist/{variant-props-BZbM__kQ.d.ts → variant-props-CVymuSfa.d.ts} +2 -2
  247. package/dist/{with-style-props-xzZLnIrF.d.ts → with-style-props-CyImx7vd.d.ts} +1 -1
  248. package/package.json +6 -6
  249. package/dist/primitive-tXm_8n_t.js +0 -2
  250. package/dist/primitive-tXm_8n_t.js.map +0 -1
  251. package/dist/resolve-pre-rendered-props-BfWe69-w.js.map +0 -1
  252. package/dist/select-B7orOUPj.js +0 -2
  253. package/dist/select-B7orOUPj.js.map +0 -1
  254. package/dist/separator-awchG4LI.js +0 -2
  255. package/dist/separator-awchG4LI.js.map +0 -1
  256. package/dist/theme-provider-BFcnjeME.js +0 -2
  257. package/dist/theme-provider-BFcnjeME.js.map +0 -1
  258. package/dist/toast-CGnquSKO.js +0 -2
  259. package/dist/toast-CGnquSKO.js.map +0 -1
  260. package/dist/types-884RJJqm.js +0 -2
  261. package/dist/use-copy-to-clipboard-CTgtLjUg.js +0 -2
@@ -1,8 +1,6 @@
1
- import { t as WithAsChild } from "./as-child-CpZKMqTE.js";
2
- import { o as WithValidation } from "./validation-CBSOmooP.js";
3
- import * as _$react from "react";
1
+ import { t as WithAsChild } from "./as-child-uN_018tj.js";
2
+ import { o as WithValidation } from "./validation-xyX_6kph.js";
4
3
  import { ComponentProps, ReactNode } from "react";
5
- import * as _$react_jsx_runtime0 from "react/jsx-runtime";
6
4
  import * as Primitive from "@ariakit/react";
7
5
 
8
6
  //#region src/components/multi-select/multi-select.d.ts
@@ -149,7 +147,7 @@ declare const MultiSelect: {
149
147
  children,
150
148
  defaultSelectedValue,
151
149
  ...props
152
- }: MultiSelectProps): _$react_jsx_runtime0.JSX.Element;
150
+ }: MultiSelectProps): import("react/jsx-runtime").JSX.Element;
153
151
  displayName: string;
154
152
  };
155
153
  /**
@@ -171,7 +169,7 @@ declare const MultiSelect: {
171
169
  * </MultiSelect.Root>
172
170
  * ```
173
171
  */
174
- readonly Trigger: _$react.ForwardRefExoticComponent<Omit<_$react.DetailedHTMLProps<_$react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & WithValidation & _$react.RefAttributes<HTMLDivElement>>;
172
+ readonly Trigger: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & WithValidation & import("react").RefAttributes<HTMLDivElement>>;
175
173
  /**
176
174
  * Renders the selected values as removable tags. Place this inside
177
175
  * `MultiSelect.Trigger`, followed by `MultiSelect.Input`.
@@ -214,7 +212,7 @@ declare const MultiSelect: {
214
212
  ({
215
213
  children,
216
214
  lockedValues
217
- }: MultiSelectTagValuesProps): _$react_jsx_runtime0.JSX.Element;
215
+ }: MultiSelectTagValuesProps): import("react/jsx-runtime").JSX.Element;
218
216
  displayName: string;
219
217
  };
220
218
  /**
@@ -236,7 +234,7 @@ declare const MultiSelect: {
236
234
  * </MultiSelect.Root>
237
235
  * ```
238
236
  */
239
- readonly Input: _$react.ForwardRefExoticComponent<Omit<MultiSelectInputProps, "ref"> & _$react.RefAttributes<HTMLInputElement>>;
237
+ readonly Input: import("react").ForwardRefExoticComponent<Omit<MultiSelectInputProps, "ref"> & import("react").RefAttributes<HTMLInputElement>>;
240
238
  /**
241
239
  * The default tag rendered inside `MultiSelect.TagValues` for each selected value.
242
240
  * Displays the value label with a remove button and keyboard navigation support.
@@ -258,7 +256,7 @@ declare const MultiSelect: {
258
256
  * </MultiSelect.Root>
259
257
  * ```
260
258
  */
261
- readonly Tag: _$react.ForwardRefExoticComponent<Omit<TagProps, "ref"> & _$react.RefAttributes<HTMLSpanElement>>;
259
+ readonly Tag: import("react").ForwardRefExoticComponent<Omit<TagProps, "ref"> & import("react").RefAttributes<HTMLSpanElement>>;
262
260
  /**
263
261
  * Renders a popover that contains multi-select content.
264
262
  *
@@ -278,7 +276,7 @@ declare const MultiSelect: {
278
276
  * </MultiSelect.Root>
279
277
  * ```
280
278
  */
281
- readonly Content: _$react.ForwardRefExoticComponent<Omit<MultiSelectContentProps, "ref"> & _$react.RefAttributes<HTMLDivElement>>;
279
+ readonly Content: import("react").ForwardRefExoticComponent<Omit<MultiSelectContentProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
282
280
  /**
283
281
  * Renders a sticky footer pinned to the bottom inside `MultiSelect.Content`,
284
282
  * with a separator border at the top.
@@ -301,7 +299,7 @@ declare const MultiSelect: {
301
299
  * </MultiSelect.Root>
302
300
  * ```
303
301
  */
304
- readonly ContentFooter: _$react.ForwardRefExoticComponent<Omit<_$react.DetailedHTMLProps<_$react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & _$react.RefAttributes<HTMLDivElement>>;
302
+ readonly ContentFooter: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
305
303
  /**
306
304
  * Renders a selectable item with a checkbox indicator inside a `MultiSelect.Content`.
307
305
  *
@@ -321,7 +319,7 @@ declare const MultiSelect: {
321
319
  * </MultiSelect.Root>
322
320
  * ```
323
321
  */
324
- readonly Item: _$react.ForwardRefExoticComponent<Omit<MultiSelectItemProps, "ref"> & _$react.RefAttributes<HTMLDivElement>>;
322
+ readonly Item: import("react").ForwardRefExoticComponent<Omit<MultiSelectItemProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
325
323
  /**
326
324
  * Renders a group for MultiSelect.Item elements.
327
325
  *
@@ -343,7 +341,7 @@ declare const MultiSelect: {
343
341
  * </MultiSelect.Root>
344
342
  * ```
345
343
  */
346
- readonly Group: _$react.ForwardRefExoticComponent<Omit<MultiSelectGroupProps, "ref"> & _$react.RefAttributes<HTMLDivElement>>;
344
+ readonly Group: import("react").ForwardRefExoticComponent<Omit<MultiSelectGroupProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
347
345
  /**
348
346
  * Renders a label in a multi-select group.
349
347
  *
@@ -365,7 +363,7 @@ declare const MultiSelect: {
365
363
  * </MultiSelect.Root>
366
364
  * ```
367
365
  */
368
- readonly GroupLabel: _$react.ForwardRefExoticComponent<Omit<MultiSelectGroupLabelProps, "ref"> & _$react.RefAttributes<HTMLDivElement>>;
366
+ readonly GroupLabel: import("react").ForwardRefExoticComponent<Omit<MultiSelectGroupLabelProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
369
367
  /**
370
368
  * Renders a description below a `MultiSelect.GroupLabel` inside a `MultiSelect.Group`.
371
369
  *
@@ -390,7 +388,7 @@ declare const MultiSelect: {
390
388
  * </MultiSelect.Root>
391
389
  * ```
392
390
  */
393
- readonly GroupDescription: _$react.ForwardRefExoticComponent<Omit<_$react.DetailedHTMLProps<_$react.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, "ref"> & _$react.RefAttributes<HTMLParagraphElement>>;
391
+ readonly GroupDescription: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, "ref"> & import("react").RefAttributes<HTMLParagraphElement>>;
394
392
  /**
395
393
  * Renders a separator between items or groups.
396
394
  *
@@ -415,10 +413,10 @@ declare const MultiSelect: {
415
413
  * </MultiSelect.Root>
416
414
  * ```
417
415
  */
418
- readonly Separator: _$react.ForwardRefExoticComponent<Omit<Omit<_$react.ClassAttributes<HTMLDivElement> & _$react.HTMLAttributes<HTMLDivElement> & WithAsChild & {
416
+ readonly Separator: import("react").ForwardRefExoticComponent<Omit<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & WithAsChild & {
419
417
  orientation?: "horizontal" | "vertical";
420
418
  semantic?: boolean;
421
- }, "ref"> & _$react.RefAttributes<HTMLDivElement>, "ref"> & _$react.RefAttributes<HTMLDivElement>>;
419
+ }, "ref"> & import("react").RefAttributes<HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
422
420
  /**
423
421
  * Renders a message when no items match the current filter.
424
422
  *
@@ -439,7 +437,7 @@ declare const MultiSelect: {
439
437
  * </MultiSelect.Root>
440
438
  * ```
441
439
  */
442
- readonly Empty: _$react.ForwardRefExoticComponent<Omit<_$react.DetailedHTMLProps<_$react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & _$react.RefAttributes<HTMLDivElement>>;
440
+ readonly Empty: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
443
441
  };
444
442
  //#endregion
445
443
  export { MultiSelect };
@@ -1,2 +1,2 @@
1
- import{t as e}from"./cx-D1HYnpvA.js";import{t}from"./icon-bWc5yC3-.js";import{t as n}from"./slot-D_ZUrdEW.js";import{t as r}from"./compose-refs-DZ3cPi47.js";import{a as i,r as a}from"./validation-BYME8rWN.js";import{n as o}from"./separator-awchG4LI.js";import{t as s}from"./field-context-B7Z1cmZW.js";import{t as c}from"./use-prefers-reduced-motion-Bpx8G3UT.js";import{createContext as l,forwardRef as u,useCallback as d,useContext as f,useEffect as p,useMemo as m,useRef as h}from"react";import{Fragment as g,jsx as _,jsxs as v}from"react/jsx-runtime";import{XIcon as y}from"@phosphor-icons/react/X";import{CheckIcon as b}from"@phosphor-icons/react/Check";import*as x from"@ariakit/react";import{LockIcon as S}from"@phosphor-icons/react/Lock";const C=e=>Array.isArray(e)&&e.every(e=>typeof e==`string`),w=[],T=l({current:null}),E=l({current:[]}),D=l({onInputKeyDownRef:{current:void 0},inputRef:{current:null}}),O=({children:e,defaultSelectedValue:t=[],...n})=>{let r=h(null),i=h(void 0),a=h(null),o=h([]),s=m(()=>({onInputKeyDownRef:i,inputRef:a}),[]);return _(T.Provider,{value:r,children:_(D.Provider,{value:s,children:_(E.Provider,{value:o,children:_(x.ComboboxProvider,{defaultSelectedValue:t,...n,children:e})})})})};O.displayName=`MultiSelect`;const k=u(({"aria-invalid":t,className:n,children:o,onKeyDown:s,onMouseDown:c,validation:l,...u},d)=>{let p=f(T),{inputRef:m}=f(D),h=x.useComboboxContext(),g=i(),{validation:v}=a({"aria-invalid":t,validation:l??g});return _(`div`,{role:`group`,"data-slot":`multi-select-trigger`,className:e(`cursor-text select-none font-sans text-sm`,`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`,`has-focus:outline-hidden has-focus-within:ring-4 has-aria-expanded:ring-4`,`has-focus-within:border-accent-600 has-focus-within:ring-focus-accent has-aria-expanded:border-accent-600 has-aria-expanded:ring-focus-accent`,`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`,`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`,`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),"data-validation":v||void 0,onKeyDown:e=>{e.key===`Escape`&&h?.getState().open&&(e.preventDefault(),h.hide()),s?.(e)},onMouseDown:e=>{e.target instanceof HTMLElement&&!e.target.closest(`button, input, [role='option']`)&&(e.preventDefault(),m.current?.focus()),c?.(e)},ref:r(p,d),...u,children:o})});k.displayName=`MultiSelectTrigger`;const A=u(({className:n,value:i,onRemove:a,locked:o=!1,onKeyDown:s,...c},l)=>{let u=h(null);return v(`span`,{ref:r(u,l),role:`option`,"aria-selected":!0,tabIndex:-1,"data-slot":`multi-select-tag`,"data-locked":o||void 0,className:e(`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`,`focus-visible:outline-hidden focus-visible:border-accent-600/50 focus-visible:ring-3 focus-visible:ring-focus-accent`,n),onKeyDown:e=>{if(o&&(e.key===`Backspace`||e.key===`Delete`)){e.preventDefault(),H(e.currentTarget);return}s?.(e)},...c,children:[i,_(`button`,{type:`button`,"aria-label":`Remove ${i}`,tabIndex:-1,"aria-disabled":o||void 0,className:e(`cursor-pointer text-strong/40 hover:bg-neutral-500/15 hover:text-strong rounded-xs p-0.5`,`aria-disabled:cursor-default aria-disabled:hover:bg-transparent aria-disabled:hover:text-strong/40`),onClick:e=>{if(e.stopPropagation(),o){let e=u.current;e&&H(e);return}a?.()},onMouseDown:e=>{e.preventDefault()},children:_(t,{svg:o?_(S,{}):_(y,{weight:`bold`}),className:`size-4`})})]})});A.displayName=`MultiSelectTag`;const j=({children:e,lockedValues:t=[]})=>{let n=x.useComboboxContext(),r=x.useStoreState(n,`selectedValue`),i=(C(r)?r:void 0)??w,a=h(i);a.current=i;let o=f(E);o.current=t;let s=m(()=>new Set(t),[t]),c=h(new Map),{onInputKeyDownRef:l,inputRef:u}=f(D),d=h(new Set);p(()=>()=>{d.current.forEach(cancelAnimationFrame)},[]);let v=e=>{let t;t=requestAnimationFrame(()=>{d.current.delete(t),e()}),d.current.add(t)},y=e=>{if(n){let t=n.getState().selectedValue;if(!C(t))return;n.setSelectedValue(t.filter(t=>t!==e))}},b=e=>{let t=a.current[e];if(t==null)return;let r=c.current.get(t);r&&(r.focus(),n?.show())},S=()=>{u.current?.focus()},T=(e,t)=>{let n=i[t];switch(e.key){case`ArrowLeft`:e.preventDefault(),t>0&&b(t-1);break;case`ArrowRight`:e.preventDefault(),t<i.length-1?b(t+1):S();break;case`Backspace`:case`Delete`:if(e.preventDefault(),n!=null){if(s.has(n)){let e=c.current.get(n);e&&H(e);break}if(y(n),e.key===`Backspace`)if(t>0){let e=t-1;v(()=>b(e))}else v(()=>{a.current.length>0?b(0):S()});else v(()=>{t<a.current.length?b(t):S()})}break;case`ArrowUp`:case`ArrowDown`:e.preventDefault(),S(),u.current?.dispatchEvent(new KeyboardEvent(`keydown`,{key:e.key,bubbles:!0,cancelable:!0,shiftKey:e.shiftKey,ctrlKey:e.ctrlKey,metaKey:e.metaKey,altKey:e.altKey}));break;default:e.key.length===1&&!e.ctrlKey&&!e.metaKey&&S();break}};return l.current=e=>{if(e.key===`ArrowLeft`&&e.currentTarget.selectionStart===0&&e.currentTarget.selectionEnd===0&&i.length>0){e.preventDefault(),b(i.length-1);return}if(e.key===`Backspace`&&e.currentTarget.value===``&&i.length>0){let e=i[i.length-1];if(e!=null)if(o.current.includes(e)){let t=c.current.get(e);t&&H(t)}else y(e)}},_(g,{children:i.map((t,n)=>{let r={value:t,locked:s.has(t),onRemove:()=>{if(s.has(t)){let e=c.current.get(t);e&&H(e);return}y(t)},ref:e=>{e?c.current.set(t,e):c.current.delete(t)},onKeyDown:e=>T(e,n),onClick:()=>b(n)};return e?e(r):_(A,{...r},t)})})};j.displayName=`MultiSelectTagValues`;const M=u(({className:t,onBlur:n,onChange:i,onFocus:a,onKeyDown:o,onValueChange:c,placeholder:l,...u},d)=>{let p=x.useComboboxContext(),{onInputKeyDownRef:m,inputRef:h}=f(D),g=f(s),v=x.useStoreState(p,`selectedValue`),y=((C(v)?v:void 0)?.length??0)>0;return _(x.Combobox,{autoSelect:!0,"data-slot":`multi-select-input`,className:e(`pointer-coarse:text-base min-w-20 flex-1 select-text border-0 bg-transparent text-sm outline-hidden`,`placeholder:select-none placeholder:text-placeholder`,t),onChange:e=>{c?.(e.target.value),i?.(e)},onKeyDown:e=>{m.current?.(e),o?.(e)},onBlur:e=>{e.relatedTarget instanceof HTMLElement&&e.relatedTarget.closest(`[data-slot="multi-select-tag"]`)&&p?.show(),n?.(e)},onFocus:e=>{p?.show(),a?.(e)},placeholder:y?void 0:l,ref:r(h,d),...u,...g?{"aria-describedby":g[`aria-describedby`],"aria-errormessage":g[`aria-errormessage`],"aria-invalid":g[`aria-invalid`],id:g.id,name:g.name}:void 0})});M.displayName=`MultiSelectInput`;const N=u(({asChild:t=!1,backdrop:r=!1,children:i,className:a,modal:o=!0,portalElement:s,sameWidth:c=!0,unmountOnHide:l=!0,...u},p)=>{let m=f(T),h=d(()=>m.current?.getBoundingClientRect()??null,[m]),g=d(e=>typeof s==`function`?s(e):s??m.current?.closest(`[data-mantle-modal-content]`)??e.ownerDocument.body,[s,m]),v=d(e=>!(e.target instanceof Node&&m.current?.contains(e.target)),[m]);return _(x.ComboboxPopover,{"data-slot":`multi-select-content`,className:e(`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`,a),backdrop:r,getAnchorRect:h,gutter:4,hideOnInteractOutside:v,modal:o,portalElement:g,ref:p,render:t?({ref:e,...t})=>_(n,{ref:e,...t}):void 0,sameWidth:c,unmountOnHide:l,...u,children:i})});N.displayName=`MultiSelectContent`;const P=u(({asChild:r=!1,children:i,className:a,focusOnHover:o=!0,value:s,onClick:c,...l},u)=>{let d=f(E),p=s!=null&&d.current.includes(s);return v(x.ComboboxItem,{"data-slot":`multi-select-item`,className:e(`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`,`[[role=option]+&]:mt-px`,`data-active-item:bg-active-menu-item`,`aria-disabled:opacity-50`,`aria-selected:bg-selected-menu-item aria-selected:data-active-item:bg-active-selected-menu-item`,a),focusOnHover:o,onClick:e=>{if(p){e.preventDefault();return}c?.(e)},ref:u,render:r?({ref:e,...t})=>_(n,{ref:e,...t}):void 0,resetValueOnSelect:!0,value:s,...l,children:[i,_(x.ComboboxItemCheck,{className:`absolute right-2 flex h-3.5 w-3.5 items-center justify-center`,children:_(t,{svg:_(b,{weight:`bold`}),className:`size-4 text-accent-600`})})]})});P.displayName=`MultiSelectItem`;const F=u(({asChild:e=!1,children:t,...r},i)=>_(x.ComboboxGroup,{"data-slot":`multi-select-group`,className:`mx-1`,ref:i,render:e?({ref:e,...t})=>_(n,{ref:e,...t}):void 0,...r,children:t}));F.displayName=`MultiSelectGroup`;const I=u(({asChild:t=!1,children:r,className:i,...a},o)=>_(x.ComboboxGroupLabel,{"data-slot":`multi-select-group-label`,className:e(`text-muted px-2 py-1 text-xs font-medium`,i),ref:o,render:t?({ref:e,...t})=>_(n,{ref:e,...t}):void 0,...a,children:r}));I.displayName=`MultiSelectGroupLabel`;const L=u(({className:t,children:n,...r},i)=>_(`p`,{"data-slot":`multi-select-group-description`,className:e(`text-muted px-2 pb-1 text-xs`,t),ref:i,...r,children:n}));L.displayName=`MultiSelectGroupDescription`;const R=u(({className:t,...n},r)=>_(o,{"data-slot":`multi-select-separator`,ref:r,className:e(`my-1 w-auto`,t),...n}));R.displayName=`MultiSelectSeparator`;const z=u(({className:t,children:n,...r},i)=>_(`div`,{"data-slot":`multi-select-empty`,className:e(`mx-1 text-muted px-2 py-6 text-center text-sm`,t),ref:i,role:`presentation`,...r,children:n}));z.displayName=`MultiSelectEmpty`;const B=u(({className:t,children:n,...r},i)=>_(`div`,{ref:i,"data-slot":`multi-select-content-footer`,"data-content-footer":!0,className:e(`bg-popover sticky bottom-0 border-t border-popover`,t),...r,children:n}));B.displayName=`MultiSelectContentFooter`;const V={Root:O,Trigger:k,TagValues:j,Input:M,Tag:A,Content:N,ContentFooter:B,Item:P,Group:F,GroupLabel:I,GroupDescription:L,Separator:R,Empty:z};function H(e){c()||e.animate([{transform:`translateX(0)`},{transform:`translateX(-4px)`},{transform:`translateX(4px)`},{transform:`translateX(-4px)`},{transform:`translateX(4px)`},{transform:`translateX(0)`}],{duration:300,easing:`ease-in-out`})}export{V as MultiSelect};
1
+ import{t as e}from"./cx-CBSnSC36.js";import{t}from"./icon-C8bYBIHW.js";import{t as n}from"./slot-CV5fmqFr.js";import{t as r}from"./compose-refs-Cjf2gfB8.js";import{a as i,r as a}from"./validation-DCyx-ceH.js";import{n as o}from"./separator-Bqjy77rG.js";import{t as s}from"./field-context-4k1kI7Bo.js";import{t as c}from"./use-prefers-reduced-motion-CWIoFA6W.js";import{createContext as l,forwardRef as u,useCallback as d,useContext as f,useEffect as p,useMemo as m,useRef as h}from"react";import{Fragment as g,jsx as _,jsxs as v}from"react/jsx-runtime";import{XIcon as y}from"@phosphor-icons/react/X";import{CheckIcon as b}from"@phosphor-icons/react/Check";import*as x from"@ariakit/react";import{LockIcon as S}from"@phosphor-icons/react/Lock";const C=e=>Array.isArray(e)&&e.every(e=>typeof e==`string`),w=[],T=l({current:null}),E=l({current:[]}),D=l({onInputKeyDownRef:{current:void 0},inputRef:{current:null}}),O=({children:e,defaultSelectedValue:t=w,...n})=>{let r=h(null),i=h(void 0),a=h(null),o=h([]),s=m(()=>({onInputKeyDownRef:i,inputRef:a}),[]);return _(T.Provider,{value:r,children:_(D.Provider,{value:s,children:_(E.Provider,{value:o,children:_(x.ComboboxProvider,{defaultSelectedValue:t,...n,children:e})})})})};O.displayName=`MultiSelect`;const k=u(({"aria-invalid":t,className:n,children:o,onKeyDown:s,onMouseDown:c,validation:l,...u},d)=>{let p=f(T),{inputRef:m}=f(D),h=x.useComboboxContext(),g=i(),{validation:v}=a({"aria-invalid":t,validation:l??g});return _(`div`,{role:`group`,"data-slot":`multi-select-trigger`,className:e(`cursor-text select-none font-sans text-sm`,`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`,`has-focus:outline-hidden has-focus-within:ring-4 has-aria-expanded:ring-4`,`has-focus-within:border-accent-600 has-focus-within:ring-focus-accent has-aria-expanded:border-accent-600 has-aria-expanded:ring-focus-accent`,`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`,`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`,`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),"data-validation":v||void 0,onKeyDown:e=>{e.key===`Escape`&&h?.getState().open&&(e.preventDefault(),h.hide()),s?.(e)},onMouseDown:e=>{e.target instanceof HTMLElement&&!e.target.closest(`button, input, [role='option']`)&&(e.preventDefault(),m.current?.focus()),c?.(e)},ref:r(p,d),...u,children:o})});k.displayName=`MultiSelectTrigger`;const A=u(({className:n,value:i,onRemove:a,locked:o=!1,onKeyDown:s,...c},l)=>{let u=h(null);return v(`span`,{ref:r(u,l),role:`option`,"aria-selected":!0,tabIndex:-1,"data-slot":`multi-select-tag`,"data-locked":o||void 0,className:e(`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`,`focus-visible:outline-hidden focus-visible:border-accent-600/50 focus-visible:ring-3 focus-visible:ring-focus-accent`,n),onKeyDown:e=>{if(o&&(e.key===`Backspace`||e.key===`Delete`)){e.preventDefault(),H(e.currentTarget);return}s?.(e)},...c,children:[i,_(`button`,{type:`button`,"aria-label":`Remove ${i}`,tabIndex:-1,"aria-disabled":o||void 0,className:e(`cursor-pointer text-strong/40 hover:bg-neutral-500/15 hover:text-strong rounded-xs p-0.5`,`aria-disabled:cursor-default aria-disabled:hover:bg-transparent aria-disabled:hover:text-strong/40`),onClick:e=>{if(e.stopPropagation(),o){let e=u.current;e&&H(e);return}a?.()},onMouseDown:e=>{e.preventDefault()},children:_(t,{svg:o?_(S,{}):_(y,{weight:`bold`}),className:`size-4`})})]})});A.displayName=`MultiSelectTag`;const j=({children:e,lockedValues:t=w})=>{let n=x.useComboboxContext(),r=x.useStoreState(n,`selectedValue`),i=(C(r)?r:void 0)??w,a=h(i);a.current=i;let o=f(E);o.current=t;let s=m(()=>new Set(t),[t]),c=h(new Map),{onInputKeyDownRef:l,inputRef:u}=f(D),d=h(new Set);p(()=>()=>{d.current.forEach(cancelAnimationFrame)},[]);let v=e=>{let t=requestAnimationFrame(()=>{d.current.delete(t),e()});d.current.add(t)},y=e=>{if(n){let t=n.getState().selectedValue;if(!C(t))return;n.setSelectedValue(t.filter(t=>t!==e))}},b=e=>{let t=a.current[e];if(t==null)return;let r=c.current.get(t);r&&(r.focus(),n?.show())},S=()=>{u.current?.focus()},T=(e,t)=>{let n=i[t];switch(e.key){case`ArrowLeft`:e.preventDefault(),t>0&&b(t-1);break;case`ArrowRight`:e.preventDefault(),t<i.length-1?b(t+1):S();break;case`Backspace`:case`Delete`:if(e.preventDefault(),n!=null){if(s.has(n)){let e=c.current.get(n);e&&H(e);break}if(y(n),e.key===`Backspace`)if(t>0){let e=t-1;v(()=>b(e))}else v(()=>{a.current.length>0?b(0):S()});else v(()=>{t<a.current.length?b(t):S()})}break;case`ArrowUp`:case`ArrowDown`:e.preventDefault(),S(),u.current?.dispatchEvent(new KeyboardEvent(`keydown`,{key:e.key,bubbles:!0,cancelable:!0,shiftKey:e.shiftKey,ctrlKey:e.ctrlKey,metaKey:e.metaKey,altKey:e.altKey}));break;default:e.key.length===1&&!e.ctrlKey&&!e.metaKey&&S();break}};return l.current=e=>{if(e.key===`ArrowLeft`&&e.currentTarget.selectionStart===0&&e.currentTarget.selectionEnd===0&&i.length>0){e.preventDefault(),b(i.length-1);return}if(e.key===`Backspace`&&e.currentTarget.value===``&&i.length>0){let e=i[i.length-1];if(e!=null)if(o.current.includes(e)){let t=c.current.get(e);t&&H(t)}else y(e)}},_(g,{children:i.map((t,n)=>{let r={value:t,locked:s.has(t),onRemove:()=>{if(s.has(t)){let e=c.current.get(t);e&&H(e);return}y(t)},ref:e=>{e?c.current.set(t,e):c.current.delete(t)},onKeyDown:e=>T(e,n),onClick:()=>b(n)};return e?e(r):_(A,{...r},t)})})};j.displayName=`MultiSelectTagValues`;const M=u(({className:t,onBlur:n,onChange:i,onFocus:a,onKeyDown:o,onValueChange:c,placeholder:l,...u},d)=>{let p=x.useComboboxContext(),{onInputKeyDownRef:m,inputRef:h}=f(D),g=f(s),v=x.useStoreState(p,`selectedValue`),y=((C(v)?v:void 0)?.length??0)>0;return _(x.Combobox,{autoSelect:!0,"data-slot":`multi-select-input`,className:e(`pointer-coarse:text-base min-w-20 flex-1 select-text border-0 bg-transparent text-sm outline-hidden`,`placeholder:select-none placeholder:text-placeholder`,t),onChange:e=>{c?.(e.target.value),i?.(e)},onKeyDown:e=>{m.current?.(e),o?.(e)},onBlur:e=>{e.relatedTarget instanceof HTMLElement&&e.relatedTarget.closest(`[data-slot="multi-select-tag"]`)&&p?.show(),n?.(e)},onFocus:e=>{p?.show(),a?.(e)},placeholder:y?void 0:l,ref:r(h,d),...u,...g?{"aria-describedby":g[`aria-describedby`],"aria-errormessage":g[`aria-errormessage`],"aria-invalid":g[`aria-invalid`],id:g.id,name:g.name}:void 0})});M.displayName=`MultiSelectInput`;const N=u(({asChild:t=!1,backdrop:r=!1,children:i,className:a,modal:o=!0,portalElement:s,sameWidth:c=!0,unmountOnHide:l=!0,...u},p)=>{let m=f(T),h=d(()=>m.current?.getBoundingClientRect()??null,[m]),g=d(e=>typeof s==`function`?s(e):s??m.current?.closest(`[data-mantle-modal-content]`)??e.ownerDocument.body,[s,m]),v=d(e=>!(e.target instanceof Node&&m.current?.contains(e.target)),[m]);return _(x.ComboboxPopover,{"data-slot":`multi-select-content`,className:e(`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`,a),backdrop:r,getAnchorRect:h,gutter:4,hideOnInteractOutside:v,modal:o,portalElement:g,ref:p,render:t?({ref:e,...t})=>_(n,{ref:e,...t}):void 0,sameWidth:c,unmountOnHide:l,...u,children:i})});N.displayName=`MultiSelectContent`;const P=u(({asChild:r=!1,children:i,className:a,focusOnHover:o=!0,value:s,onClick:c,...l},u)=>{let d=f(E),p=s!=null&&d.current.includes(s);return v(x.ComboboxItem,{"data-slot":`multi-select-item`,className:e(`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`,`[[role=option]+&]:mt-px`,`data-active-item:bg-active-menu-item`,`aria-disabled:opacity-50`,`aria-selected:bg-selected-menu-item aria-selected:data-active-item:bg-active-selected-menu-item`,a),focusOnHover:o,onClick:e=>{if(p){e.preventDefault();return}c?.(e)},ref:u,render:r?({ref:e,...t})=>_(n,{ref:e,...t}):void 0,resetValueOnSelect:!0,value:s,...l,children:[i,_(x.ComboboxItemCheck,{className:`absolute right-2 flex h-3.5 w-3.5 items-center justify-center`,children:_(t,{svg:_(b,{weight:`bold`}),className:`size-4 text-accent-600`})})]})});P.displayName=`MultiSelectItem`;const F=u(({asChild:e=!1,children:t,...r},i)=>_(x.ComboboxGroup,{"data-slot":`multi-select-group`,className:`mx-1`,ref:i,render:e?({ref:e,...t})=>_(n,{ref:e,...t}):void 0,...r,children:t}));F.displayName=`MultiSelectGroup`;const I=u(({asChild:t=!1,children:r,className:i,...a},o)=>_(x.ComboboxGroupLabel,{"data-slot":`multi-select-group-label`,className:e(`text-muted px-2 py-1 text-xs font-medium`,i),ref:o,render:t?({ref:e,...t})=>_(n,{ref:e,...t}):void 0,...a,children:r}));I.displayName=`MultiSelectGroupLabel`;const L=u(({className:t,children:n,...r},i)=>_(`p`,{"data-slot":`multi-select-group-description`,className:e(`text-muted px-2 pb-1 text-xs`,t),ref:i,...r,children:n}));L.displayName=`MultiSelectGroupDescription`;const R=u(({className:t,...n},r)=>_(o,{"data-slot":`multi-select-separator`,ref:r,className:e(`my-1 w-auto`,t),...n}));R.displayName=`MultiSelectSeparator`;const z=u(({className:t,children:n,...r},i)=>_(`div`,{"data-slot":`multi-select-empty`,className:e(`mx-1 text-muted px-2 py-6 text-center text-sm`,t),ref:i,role:`presentation`,...r,children:n}));z.displayName=`MultiSelectEmpty`;const B=u(({className:t,children:n,...r},i)=>_(`div`,{ref:i,"data-slot":`multi-select-content-footer`,"data-content-footer":!0,className:e(`bg-popover sticky bottom-0 border-t border-popover`,t),...r,children:n}));B.displayName=`MultiSelectContentFooter`;const V={Root:O,Trigger:k,TagValues:j,Input:M,Tag:A,Content:N,ContentFooter:B,Item:P,Group:F,GroupLabel:I,GroupDescription:L,Separator:R,Empty:z};function H(e){c()||e.animate([{transform:`translateX(0)`},{transform:`translateX(-4px)`},{transform:`translateX(4px)`},{transform:`translateX(-4px)`},{transform:`translateX(4px)`},{transform:`translateX(0)`}],{duration:300,easing:`ease-in-out`})}export{V as MultiSelect};
2
2
  //# sourceMappingURL=multi-select.js.map
@@ -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 { FieldControlContext } from \"../field/field-context.js\";\nimport { parseValidation, useFieldValidation } from \"../field/validation.js\";\nimport type { WithValidation } from \"../field/validation.js\";\nimport { Icon } from \"../icon/icon.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 * Use MultiSelect when the user can choose multiple values from a list, with selected\n * items rendered as removable tags/chips. For single selection, use Combobox (with search)\n * or Select (without).\n *\n * When composing with `Field.Item`, wrap `MultiSelect.Root` in `Field.Control`.\n * `Field.Control` flows the generated `id`, `name`, `aria-describedby`,\n * `aria-errormessage`, and `aria-invalid` through to the focusable\n * `MultiSelect.Input` via `FieldControlContext`.\n *\n * @see https://mantle.ngrok.com/components/multi-select#multiselectroot\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 * @see https://mantle.ngrok.com/components/multi-select#multiselecttrigger\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 fieldValidation = useFieldValidation();\n\t\tconst { validation } = parseValidation({\n\t\t\t\"aria-invalid\": _ariaInvalid,\n\t\t\tvalidation: _validation ?? fieldValidation,\n\t\t});\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 * @see https://mantle.ngrok.com/components/multi-select#multiselecttag\n *\n * @example\n * ```tsx\n * <MultiSelect.Root>\n * <MultiSelect.Trigger>\n * <MultiSelect.TagValues>\n * {(props) => <MultiSelect.Tag key={props.value} {...props} />}\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 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 * @see https://mantle.ngrok.com/components/multi-select#multiselecttagvalues\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 * `MultiSelect.Input` is the focusable element of the multi-select. When the\n * surrounding `MultiSelect.Root` is wrapped in `Field.Control`, the generated\n * `id`, `aria-invalid`, `aria-describedby`, and `aria-errormessage` flow onto\n * the input here via `FieldControlContext`.\n *\n * @see https://mantle.ngrok.com/components/multi-select#multiselectinput\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 fieldControl = useContext(FieldControlContext);\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\t{...(fieldControl\n\t\t\t\t\t? {\n\t\t\t\t\t\t\t\"aria-describedby\": fieldControl[\"aria-describedby\"],\n\t\t\t\t\t\t\t\"aria-errormessage\": fieldControl[\"aria-errormessage\"],\n\t\t\t\t\t\t\t\"aria-invalid\": fieldControl[\"aria-invalid\"],\n\t\t\t\t\t\t\tid: fieldControl.id,\n\t\t\t\t\t\t\tname: fieldControl.name,\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined)}\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 * @see https://mantle.ngrok.com/components/multi-select#multiselectcontent\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 * @see https://mantle.ngrok.com/components/multi-select#multiselectitem\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 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 * @see https://mantle.ngrok.com/components/multi-select#multiselectgroup\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.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 * </MultiSelect.Root>\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 * @see https://mantle.ngrok.com/components/multi-select#multiselectgrouplabel\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.Group>\n * <MultiSelect.GroupLabel>Fruits</MultiSelect.GroupLabel>\n * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n * </MultiSelect.Group>\n * </MultiSelect.Content>\n * </MultiSelect.Root>\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 * @see https://mantle.ngrok.com/components/multi-select#multiselectgroupdescription\n *\n * @example\n * ```tsx\n * <MultiSelect.Root>\n * <MultiSelect.Trigger>\n * <MultiSelect.TagValues />\n * <MultiSelect.Input placeholder=\"Select regions...\" />\n * </MultiSelect.Trigger>\n * <MultiSelect.Content>\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 * </MultiSelect.Content>\n * </MultiSelect.Root>\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 * @see https://mantle.ngrok.com/components/multi-select#multiselectseparator\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.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 * </MultiSelect.Root>\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 * @see https://mantle.ngrok.com/components/multi-select#multiselectempty\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 * {matches.length === 0 && (\n * <MultiSelect.Empty>No results found</MultiSelect.Empty>\n * )}\n * </MultiSelect.Content>\n * </MultiSelect.Root>\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 * @see https://mantle.ngrok.com/components/multi-select#multiselectcontentfooter\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.ContentFooter>\n * <p>Upgrade to unlock more options.</p>\n * <Button>Upgrade</Button>\n * </MultiSelect.ContentFooter>\n * </MultiSelect.Content>\n * </MultiSelect.Root>\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 * Use MultiSelect when the user can choose multiple values from a list, with selected\n * items rendered as removable tags/chips. For single selection, use Combobox (with search)\n * or Select (without).\n *\n * @see https://mantle.ngrok.com/components/multi-select\n * @see https://www.w3.org/WAI/ARIA/apg/patterns/combobox/\n * @see https://ariakit.org/components/combobox\n *\n * @example\n * Composition:\n * ```\n * MultiSelect.Root\n * ├── MultiSelect.Trigger\n * │ ├── MultiSelect.TagValues\n * │ └── MultiSelect.Input\n * └── MultiSelect.Content\n * ├── MultiSelect.Group\n * │ ├── MultiSelect.GroupLabel\n * │ ├── MultiSelect.GroupDescription\n * │ └── MultiSelect.Item\n * ├── MultiSelect.Separator\n * ├── MultiSelect.Empty\n * └── MultiSelect.ContentFooter\n * ```\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 * Use MultiSelect when the user can choose multiple values from a list, with selected\n\t * items rendered as removable tags/chips. For single selection, use Combobox (with search)\n\t * or Select (without).\n\t *\n\t * @see https://mantle.ngrok.com/components/multi-select#multiselectroot\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 * @see https://mantle.ngrok.com/components/multi-select#multiselecttrigger\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\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 * @see https://mantle.ngrok.com/components/multi-select#multiselecttagvalues\n\t *\n\t * @example\n\t * ```tsx\n\t * <MultiSelect.Root>\n\t * <MultiSelect.Trigger>\n\t * <MultiSelect.TagValues lockedValues={[\"global\"]} />\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\t * @example\n\t * Custom tags via children render function — `locked` is forwarded via props.\n\t * ```tsx\n\t * <MultiSelect.Root>\n\t * <MultiSelect.Trigger>\n\t * <MultiSelect.TagValues lockedValues={[\"global\"]}>\n\t * {(props) => <MultiSelect.Tag key={props.value} {...props} />}\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\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 * @see https://mantle.ngrok.com/components/multi-select#multiselectinput\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\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 * @see https://mantle.ngrok.com/components/multi-select#multiselecttag\n\t *\n\t * @example\n\t * ```tsx\n\t * <MultiSelect.Root>\n\t * <MultiSelect.Trigger>\n\t * <MultiSelect.TagValues>\n\t * {(props) => <MultiSelect.Tag key={props.value} {...props} />}\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\tTag,\n\t/**\n\t * Renders a popover that contains multi-select content.\n\t *\n\t * @see https://mantle.ngrok.com/components/multi-select#multiselectcontent\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.Item value=\"banana\">Banana</MultiSelect.Item>\n\t * </MultiSelect.Content>\n\t * </MultiSelect.Root>\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 * @see https://mantle.ngrok.com/components/multi-select#multiselectcontentfooter\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.ContentFooter>\n\t * <p>Upgrade to unlock more options.</p>\n\t * </MultiSelect.ContentFooter>\n\t * </MultiSelect.Content>\n\t * </MultiSelect.Root>\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 * @see https://mantle.ngrok.com/components/multi-select#multiselectitem\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.Item value=\"banana\">Banana</MultiSelect.Item>\n\t * </MultiSelect.Content>\n\t * </MultiSelect.Root>\n\t * ```\n\t */\n\tItem,\n\t/**\n\t * Renders a group for MultiSelect.Item elements.\n\t *\n\t * @see https://mantle.ngrok.com/components/multi-select#multiselectgroup\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.Group>\n\t * <MultiSelect.GroupLabel>Fruits</MultiSelect.GroupLabel>\n\t * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n\t * </MultiSelect.Group>\n\t * </MultiSelect.Content>\n\t * </MultiSelect.Root>\n\t * ```\n\t */\n\tGroup,\n\t/**\n\t * Renders a label in a multi-select group.\n\t *\n\t * @see https://mantle.ngrok.com/components/multi-select#multiselectgrouplabel\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.Group>\n\t * <MultiSelect.GroupLabel>Fruits</MultiSelect.GroupLabel>\n\t * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n\t * </MultiSelect.Group>\n\t * </MultiSelect.Content>\n\t * </MultiSelect.Root>\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 * @see https://mantle.ngrok.com/components/multi-select#multiselectgroupdescription\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 regions...\" />\n\t * </MultiSelect.Trigger>\n\t * <MultiSelect.Content>\n\t * <MultiSelect.Group>\n\t * <MultiSelect.GroupLabel>Regional Aliases</MultiSelect.GroupLabel>\n\t * <MultiSelect.GroupDescription>\n\t * Include all points of presence within the region.\n\t * </MultiSelect.GroupDescription>\n\t * <MultiSelect.Item value=\"global\">global</MultiSelect.Item>\n\t * </MultiSelect.Group>\n\t * </MultiSelect.Content>\n\t * </MultiSelect.Root>\n\t * ```\n\t */\n\tGroupDescription,\n\t/**\n\t * Renders a separator between items or groups.\n\t *\n\t * @see https://mantle.ngrok.com/components/multi-select#multiselectseparator\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.Group>\n\t * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n\t * </MultiSelect.Group>\n\t * <MultiSelect.Separator />\n\t * <MultiSelect.Group>\n\t * <MultiSelect.Item value=\"carrot\">Carrot</MultiSelect.Item>\n\t * </MultiSelect.Group>\n\t * </MultiSelect.Content>\n\t * </MultiSelect.Root>\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 * @see https://mantle.ngrok.com/components/multi-select#multiselectempty\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 * {matches.length === 0 && (\n\t * <MultiSelect.Empty>No results found</MultiSelect.Empty>\n\t * )}\n\t * </MultiSelect.Content>\n\t * </MultiSelect.Root>\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":"wuBAmCA,MAAM,EAAiB,GACtB,MAAM,QAAQ,EAAM,EAAI,EAAM,MAAO,GAAS,OAAO,GAAS,SAAS,CAGlE,EAAwB,EAAE,CAE1B,EAAoB,EAAgD,CAAE,QAAS,KAAM,CAAC,CAOtF,EAAsB,EAAqC,CAAE,QAAS,EAAE,CAAE,CAAC,CAc3E,EAAmB,EAAqC,CAC7D,kBAAmB,CAAE,QAAS,IAAA,GAAW,CACzC,SAAU,CAAE,QAAS,KAAM,CAC3B,CAAC,CAiCI,GAAQ,CAAE,WAAU,uBAAuB,EAAE,CAAE,GAAG,KAA8B,CACrF,IAAM,EAAa,EAA8B,KAAK,CAChD,EAAoB,EACzB,IAAA,GACA,CACK,EAAW,EAAgC,KAAK,CAChD,EAAkB,EAAiB,EAAE,CAAC,CACtC,EAAY,OAAe,CAAE,oBAAmB,WAAU,EAAG,EAAE,CAAC,CAEtE,OACC,EAAC,EAAkB,SAAnB,CAA4B,MAAO,WAClC,EAAC,EAAiB,SAAlB,CAA2B,MAAO,WACjC,EAAC,EAAoB,SAArB,CAA8B,MAAO,WACpC,EAAC,EAAU,iBAAX,CACuB,uBACtB,GAAI,EAEH,WAC2B,CAAA,CACC,CAAA,CACJ,CAAA,CACA,CAAA,EAG/B,EAAK,YAAc,cAuBnB,MAAM,EAAU,GAEd,CACC,eAAgB,EAChB,YACA,WACA,YACA,cACA,WAAY,EACZ,GAAG,GAEJ,IACI,CACJ,IAAM,EAAa,EAAW,EAAkB,CAC1C,CAAE,YAAa,EAAW,EAAiB,CAC3C,EAAQ,EAAU,oBAAoB,CACtC,EAAkB,GAAoB,CACtC,CAAE,cAAe,EAAgB,CACtC,eAAgB,EAChB,WAAY,GAAe,EAC3B,CAAC,CAEF,OACC,EAAC,MAAD,CACC,KAAK,QACL,YAAU,uBACV,UAAW,EACV,4CACA,uJACA,4EACA,gJACA,+RACA,+RACA,gRACA,EACA,CACD,kBAAiB,GAAc,IAAA,GAC/B,UAAY,GAAU,CACjB,EAAM,MAAQ,UAAY,GAAO,UAAU,CAAC,OAC/C,EAAM,gBAAgB,CACtB,EAAM,MAAM,EAEb,IAAY,EAAM,EAEnB,YAAc,GAAU,CAKtB,EAAM,kBAAkB,aACxB,CAAC,EAAM,OAAO,QAAQ,iCAAiC,GAEvD,EAAM,gBAAgB,CACtB,EAAS,SAAS,OAAO,EAE1B,IAAc,EAAM,EAErB,IAAK,EAAY,EAAY,EAAI,CACjC,GAAI,EAEH,WACI,CAAA,EAGR,CACD,EAAQ,YAAc,qBA0CtB,MAAM,EAAM,GACV,CAAE,YAAW,QAAO,WAAU,SAAS,GAAO,YAAW,GAAG,GAAS,IAAQ,CAC7E,IAAM,EAAc,EAA+B,KAAK,CAExD,OACC,EAAC,OAAD,CACC,IAAK,EAAY,EAAa,EAAI,CAClC,KAAK,SACL,gBAAA,GACA,SAAU,GACV,YAAU,mBACV,cAAa,GAAU,IAAA,GACvB,UAAW,EACV,6JACA,uHACA,EACA,CACD,UAAY,GAAU,CACrB,GAAI,IAAW,EAAM,MAAQ,aAAe,EAAM,MAAQ,UAAW,CACpE,EAAM,gBAAgB,CACtB,EAAa,EAAM,cAAc,CACjC,OAED,IAAY,EAAM,EAEnB,GAAI,WApBL,CAsBE,EACD,EAAC,SAAD,CACC,KAAK,SACL,aAAY,UAAU,IACtB,SAAU,GACV,gBAAe,GAAU,IAAA,GACzB,UAAW,EACV,2FACA,qGACA,CACD,QAAU,GAAU,CAGnB,GADA,EAAM,iBAAiB,CACnB,EAAQ,CAEX,IAAM,EAAa,EAAY,QAC3B,GACH,EAAa,EAAW,CAEzB,OAED,KAAY,EAEb,YAAc,GAAU,CAEvB,EAAM,gBAAgB,WAGvB,EAAC,EAAD,CAAM,IAAK,EAAS,EAAC,EAAD,EAAY,CAAA,CAAG,EAAC,EAAD,CAAO,OAAO,OAAS,CAAA,CAAE,UAAU,SAAW,CAAA,CACzE,CAAA,CACH,IAGT,CACD,EAAI,YAAc,iBA+DlB,MAAM,GAAa,CAAE,WAAU,eAAe,EAAE,IAAkC,CACjF,IAAM,EAAQ,EAAU,oBAAoB,CACtC,EAAmB,EAAU,cAAc,EAAO,gBAAgB,CAElE,GADiB,EAAc,EAAiB,CAAG,EAAmB,IAAA,KACpC,EAGlC,EAAmB,EAAiB,EAAc,CACxD,EAAiB,QAAU,EAI3B,IAAM,EAAkB,EAAW,EAAoB,CACvD,EAAgB,QAAU,EAC1B,IAAM,EAAkB,MAAc,IAAI,IAAI,EAAa,CAAE,CAAC,EAAa,CAAC,CACtE,EAAU,EAAqC,IAAI,IAAM,CACzD,CAAE,oBAAmB,YAAa,EAAW,EAAiB,CAG9D,EAAiB,EAAoB,IAAI,IAAM,CACrD,UACa,CACX,EAAe,QAAQ,QAAQ,qBAAqB,EAErD,EAAE,CACF,CACD,IAAM,EAAO,GAA+B,CAC3C,IAAI,EACJ,EAAK,0BAA4B,CAEhC,EAAe,QAAQ,OAAO,EAAG,CACjC,GAAU,EACT,CACF,EAAe,QAAQ,IAAI,EAAG,EAGzB,EAAe,GAAkB,CACtC,GAAI,EAAO,CACV,IAAM,EAAW,EAAM,UAAU,CAAC,cAClC,GAAI,CAAC,EAAc,EAAS,CAC3B,OAED,EAAM,iBAAiB,EAAS,OAAQ,GAAM,IAAM,EAAM,CAAC,GAIvD,EAAY,GAAkB,CACnC,IAAM,EAAQ,EAAiB,QAAQ,GACvC,GAAI,GAAS,KACZ,OAED,IAAM,EAAa,EAAQ,QAAQ,IAAI,EAAM,CACzC,IACH,EAAW,OAAO,CAGlB,GAAO,MAAM,GAIT,MAAmB,CACxB,EAAS,SAAS,OAAO,EAGpB,GAAoB,EAAuC,IAAkB,CAClF,IAAM,EAAQ,EAAc,GAC5B,OAAQ,EAAM,IAAd,CACC,IAAK,YACJ,EAAM,gBAAgB,CAClB,EAAQ,GACX,EAAS,EAAQ,EAAE,CAEpB,MAED,IAAK,aACJ,EAAM,gBAAgB,CAClB,EAAQ,EAAc,OAAS,EAClC,EAAS,EAAQ,EAAE,CAEnB,GAAY,CAEb,MAED,IAAK,YACL,IAAK,SAEJ,GADA,EAAM,gBAAgB,CAClB,GAAS,KAAM,CAElB,GAAI,EAAgB,IAAI,EAAM,CAAE,CAC/B,IAAM,EAAa,EAAQ,QAAQ,IAAI,EAAM,CACzC,GACH,EAAa,EAAW,CAEzB,MAID,GAFA,EAAY,EAAM,CAEd,EAAM,MAAQ,YACjB,GAAI,EAAQ,EAAG,CAGd,IAAM,EAAY,EAAQ,EAC1B,MAAU,EAAS,EAAU,CAAC,MAE9B,MAAU,CACL,EAAiB,QAAQ,OAAS,EACrC,EAAS,EAAE,CAEX,GAAY,EAEZ,MAIH,MAAU,CAEL,EAAQ,EAAiB,QAAQ,OACpC,EAAS,EAAM,CAEf,GAAY,EAEZ,CAGJ,MAED,IAAK,UACL,IAAK,YAGJ,EAAM,gBAAgB,CACtB,GAAY,CACZ,EAAS,SAAS,cACjB,IAAI,cAAc,UAAW,CAC5B,IAAK,EAAM,IACX,QAAS,GACT,WAAY,GACZ,SAAU,EAAM,SAChB,QAAS,EAAM,QACf,QAAS,EAAM,QACf,OAAQ,EAAM,OACd,CAAC,CACF,CACD,MAED,QAEK,EAAM,IAAI,SAAW,GAAK,CAAC,EAAM,SAAW,CAAC,EAAM,SACtD,GAAY,CAEb,QAoCH,MAFA,GAAkB,QA7BU,GAA2C,CACtE,GACC,EAAM,MAAQ,aACd,EAAM,cAAc,iBAAmB,GACvC,EAAM,cAAc,eAAiB,GACrC,EAAc,OAAS,EACtB,CACD,EAAM,gBAAgB,CACtB,EAAS,EAAc,OAAS,EAAE,CAClC,OAED,GAAI,EAAM,MAAQ,aAAe,EAAM,cAAc,QAAU,IAAM,EAAc,OAAS,EAAG,CAC9F,IAAM,EAAY,EAAc,EAAc,OAAS,GACvD,GAAI,GAAa,KAChB,GAAI,EAAgB,QAAQ,SAAS,EAAU,CAAE,CAEhD,IAAM,EAAa,EAAQ,QAAQ,IAAI,EAAU,CAC7C,GACH,EAAa,EAAW,MAGzB,EAAY,EAAU,GAWzB,EAAA,EAAA,CAAA,SACE,EAAc,KAAK,EAAO,IAAU,CACpC,IAAM,EAAiC,CACtC,QACA,OAAQ,EAAgB,IAAI,EAAM,CAClC,aAAgB,CAGf,GAAI,EAAgB,IAAI,EAAM,CAAE,CAC/B,IAAM,EAAa,EAAQ,QAAQ,IAAI,EAAM,CACzC,GACH,EAAa,EAAW,CAEzB,OAED,EAAY,EAAM,EAEnB,IAAM,GAAiC,CAClC,EACH,EAAQ,QAAQ,IAAI,EAAO,EAAK,CAEhC,EAAQ,QAAQ,OAAO,EAAM,EAG/B,UAAY,GAA0C,EAAiB,EAAO,EAAM,CAGpF,YAAe,EAAS,EAAM,CAC9B,CAMD,OAJI,EACI,EAAS,EAAe,CAGzB,EAAC,EAAD,CAAiB,GAAI,EAAkB,CAA7B,EAA6B,EAC7C,CACA,CAAA,EAGL,EAAU,YAAc,uBAmCxB,MAAM,EAAQ,GAEZ,CAAE,YAAW,SAAQ,WAAU,UAAS,YAAW,gBAAe,cAAa,GAAG,GAClF,IACI,CACJ,IAAM,EAAQ,EAAU,oBAAoB,CACtC,CAAE,oBAAmB,YAAa,EAAW,EAAiB,CAC9D,EAAe,EAAW,EAAoB,CAC9C,EAAmB,EAAU,cAAc,EAAO,gBAAgB,CAElE,IADiB,EAAc,EAAiB,CAAG,EAAmB,IAAA,KACjC,QAAU,GAAK,EAE1D,OACC,EAAC,EAAU,SAAX,CACC,WAAA,GACA,YAAU,qBACV,UAAW,EACV,sGACA,uDACA,EACA,CACD,SAAW,GAAU,CACpB,IAAgB,EAAM,OAAO,MAAM,CACnC,IAAW,EAAM,EAElB,UAAY,GAAU,CACrB,EAAkB,UAAU,EAAM,CAClC,IAAY,EAAM,EAEnB,OAAS,GAAU,CAKjB,EAAM,yBAAyB,aAC/B,EAAM,cAAc,QAAQ,iCAAiC,EAE7D,GAAO,MAAM,CAEd,IAAS,EAAM,EAEhB,QAAU,GAAU,CAGnB,GAAO,MAAM,CACb,IAAU,EAAM,EAEjB,YAAa,EAAoB,IAAA,GAAY,EAE7C,IAAK,EAAY,EAAU,EAAI,CAC/B,GAAI,EACJ,GAAK,EACF,CACA,mBAAoB,EAAa,oBACjC,oBAAqB,EAAa,qBAClC,eAAgB,EAAa,gBAC7B,GAAI,EAAa,GACjB,KAAM,EAAa,KACnB,CACA,IAAA,GACF,CAAA,EAGJ,CACD,EAAM,YAAc,mBAwBpB,MAAM,EAAU,GAEd,CACC,UAAU,GACV,WAAW,GACX,WACA,YACA,QAAQ,GACR,gBACA,YAAY,GACZ,gBAAgB,GAChB,GAAG,GAEJ,IACI,CACJ,IAAM,EAAa,EAAW,EAAkB,CAE1C,EAAgB,MACd,EAAW,SAAS,uBAAuB,EAAI,KACpD,CAAC,EAAW,CAAC,CAEV,EAAmB,EACvB,GACI,OAAO,GAAkB,WACrB,EAAc,EAAQ,CAI7B,GACA,EAAW,SAAS,QAAqB,8BAA8B,EACvE,EAAQ,cAAc,KAGxB,CAAC,EAAe,EAAW,CAC3B,CAEK,EAAwB,EAC5B,GAIA,EAAI,EAAM,kBAAkB,MAAQ,EAAW,SAAS,SAAS,EAAM,OAAO,EAK/E,CAAC,EAAW,CACZ,CAED,OACC,EAAC,EAAU,gBAAX,CACC,YAAU,uBACV,UAAW,EACV,mPACA,EACA,CACS,WACK,gBACf,OAAQ,EACe,wBAChB,QACP,cAAe,EACV,MACL,OACC,GAAW,CAAE,MAAK,GAAG,KAAiB,EAAC,EAAD,CAAW,MAAK,GAAI,EAAc,CAAA,CAAG,IAAA,GAEjE,YACI,gBACf,GAAI,EAEH,WAC0B,CAAA,EAG9B,CACD,EAAQ,YAAc,qBAwBtB,MAAM,EAAO,GAEX,CAAE,UAAU,GAAO,WAAU,YAAW,eAAe,GAAM,QAAO,UAAS,GAAG,GAChF,IACI,CACJ,IAAM,EAAkB,EAAW,EAAoB,CACjD,EAAW,GAAS,MAAQ,EAAgB,QAAQ,SAAS,EAAM,CAEzE,OACC,EAAC,EAAU,aAAX,CACC,YAAU,oBACV,UAAW,EACV,2HACA,0BACA,uCACA,2BACA,kGACA,EACA,CACa,eACd,QAAU,GAAU,CAGnB,GAAI,EAAU,CACb,EAAM,gBAAgB,CACtB,OAED,IAAU,EAAM,EAEZ,MACL,OACC,GAAW,CAAE,MAAK,GAAG,KAAiB,EAAC,EAAD,CAAW,MAAK,GAAI,EAAc,CAAA,CAAG,IAAA,GAE5E,mBAAA,GACO,QACP,GAAI,WA1BL,CA4BE,EACD,EAAC,EAAU,kBAAX,CAA6B,UAAU,yEACtC,EAAC,EAAD,CAAM,IAAK,EAAC,EAAD,CAAW,OAAO,OAAS,CAAA,CAAE,UAAU,yBAA2B,CAAA,CAChD,CAAA,CACN,IAG3B,CACD,EAAK,YAAc,kBA0BnB,MAAM,EAAQ,GACZ,CAAE,UAAU,GAAO,WAAU,GAAG,GAAS,IAExC,EAAC,EAAU,cAAX,CACC,YAAU,qBACV,UAAU,OACL,MACL,OACC,GAAW,CAAE,MAAK,GAAG,KAAiB,EAAC,EAAD,CAAW,MAAK,GAAI,EAAc,CAAA,CAAG,IAAA,GAE5E,GAAI,EAEH,WACwB,CAAA,CAG5B,CACD,EAAM,YAAc,mBAyBpB,MAAM,EAAa,GACjB,CAAE,UAAU,GAAO,WAAU,YAAW,GAAG,GAAS,IAEnD,EAAC,EAAU,mBAAX,CACC,YAAU,2BACV,UAAW,EAAG,2CAA4C,EAAU,CAC/D,MACL,OACC,GAAW,CAAE,MAAK,GAAG,KAAiB,EAAC,EAAD,CAAW,MAAK,GAAI,EAAc,CAAA,CAAG,IAAA,GAE5E,GAAI,EAEH,WAC6B,CAAA,CAGjC,CACD,EAAW,YAAc,wBA6BzB,MAAM,EAAmB,GACvB,CAAE,YAAW,WAAU,GAAG,GAAS,IAElC,EAAC,IAAD,CACC,YAAU,iCACV,UAAW,EAAG,+BAAgC,EAAU,CACnD,MACL,GAAI,EAEH,WACE,CAAA,CAGN,CACD,EAAiB,YAAc,8BA0B/B,MAAM,EAAgC,GAGnC,CAAE,YAAW,GAAG,GAAS,IAC3B,EAAC,EAAD,CACC,YAAU,yBACL,MACL,UAAW,EAAG,cAAe,EAAU,CACvC,GAAI,EACH,CAAA,CACD,CACF,EAA8B,YAAc,uBAwB5C,MAAM,EAAQ,GACZ,CAAE,YAAW,WAAU,GAAG,GAAS,IAElC,EAAC,MAAD,CACC,YAAU,qBACV,UAAW,EAAG,gDAAiD,EAAU,CACpE,MACL,KAAK,eACL,GAAI,EAEH,WACI,CAAA,CAGR,CACD,EAAM,YAAc,mBA2BpB,MAAM,EAAgB,GACpB,CAAE,YAAW,WAAU,GAAG,GAAS,IAElC,EAAC,MAAD,CACM,MACL,YAAU,8BACV,sBAAA,GACA,UAAW,EAAG,qDAAsD,EAAU,CAC9E,GAAI,EAEH,WACI,CAAA,CAGR,CACD,EAAc,YAAc,2BAiD5B,MAAM,EAAc,CAwBnB,OAoBA,UAuCA,YAoBA,QAsBA,MAoBA,UAuBA,gBAoBA,OAsBA,QAsBA,aAyBA,mBAyBA,UAAW,EAqBX,QACA,CAYD,SAAS,EAAa,EAA4B,CAI7C,GAAyB,EAI7B,EAAQ,QACP,CACC,CAAE,UAAW,gBAAiB,CAC9B,CAAE,UAAW,mBAAoB,CACjC,CAAE,UAAW,kBAAmB,CAChC,CAAE,UAAW,mBAAoB,CACjC,CAAE,UAAW,kBAAmB,CAChC,CAAE,UAAW,gBAAiB,CAC9B,CACD,CAAE,SAAU,IAAK,OAAQ,cAAe,CACxC"}
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 { FieldControlContext } from \"../field/field-context.js\";\nimport { parseValidation, useFieldValidation } from \"../field/validation.js\";\nimport type { WithValidation } from \"../field/validation.js\";\nimport { Icon } from \"../icon/icon.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 * Use MultiSelect when the user can choose multiple values from a list, with selected\n * items rendered as removable tags/chips. For single selection, use Combobox (with search)\n * or Select (without).\n *\n * When composing with `Field.Item`, wrap `MultiSelect.Root` in `Field.Control`.\n * `Field.Control` flows the generated `id`, `name`, `aria-describedby`,\n * `aria-errormessage`, and `aria-invalid` through to the focusable\n * `MultiSelect.Input` via `FieldControlContext`.\n *\n * @see https://mantle.ngrok.com/components/multi-select#multiselectroot\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 = EMPTY_ARRAY, ...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 * @see https://mantle.ngrok.com/components/multi-select#multiselecttrigger\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 fieldValidation = useFieldValidation();\n\t\tconst { validation } = parseValidation({\n\t\t\t\"aria-invalid\": _ariaInvalid,\n\t\t\tvalidation: _validation ?? fieldValidation,\n\t\t});\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 * @see https://mantle.ngrok.com/components/multi-select#multiselecttag\n *\n * @example\n * ```tsx\n * <MultiSelect.Root>\n * <MultiSelect.Trigger>\n * <MultiSelect.TagValues>\n * {(props) => <MultiSelect.Tag key={props.value} {...props} />}\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 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 * @see https://mantle.ngrok.com/components/multi-select#multiselecttagvalues\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 = EMPTY_ARRAY }: 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\tconst id = 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 * `MultiSelect.Input` is the focusable element of the multi-select. When the\n * surrounding `MultiSelect.Root` is wrapped in `Field.Control`, the generated\n * `id`, `aria-invalid`, `aria-describedby`, and `aria-errormessage` flow onto\n * the input here via `FieldControlContext`.\n *\n * @see https://mantle.ngrok.com/components/multi-select#multiselectinput\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 fieldControl = useContext(FieldControlContext);\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\t{...(fieldControl\n\t\t\t\t\t? {\n\t\t\t\t\t\t\t\"aria-describedby\": fieldControl[\"aria-describedby\"],\n\t\t\t\t\t\t\t\"aria-errormessage\": fieldControl[\"aria-errormessage\"],\n\t\t\t\t\t\t\t\"aria-invalid\": fieldControl[\"aria-invalid\"],\n\t\t\t\t\t\t\tid: fieldControl.id,\n\t\t\t\t\t\t\tname: fieldControl.name,\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined)}\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 * @see https://mantle.ngrok.com/components/multi-select#multiselectcontent\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 * @see https://mantle.ngrok.com/components/multi-select#multiselectitem\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 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 * @see https://mantle.ngrok.com/components/multi-select#multiselectgroup\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.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 * </MultiSelect.Root>\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 * @see https://mantle.ngrok.com/components/multi-select#multiselectgrouplabel\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.Group>\n * <MultiSelect.GroupLabel>Fruits</MultiSelect.GroupLabel>\n * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n * </MultiSelect.Group>\n * </MultiSelect.Content>\n * </MultiSelect.Root>\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 * @see https://mantle.ngrok.com/components/multi-select#multiselectgroupdescription\n *\n * @example\n * ```tsx\n * <MultiSelect.Root>\n * <MultiSelect.Trigger>\n * <MultiSelect.TagValues />\n * <MultiSelect.Input placeholder=\"Select regions...\" />\n * </MultiSelect.Trigger>\n * <MultiSelect.Content>\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 * </MultiSelect.Content>\n * </MultiSelect.Root>\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 * @see https://mantle.ngrok.com/components/multi-select#multiselectseparator\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.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 * </MultiSelect.Root>\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 * @see https://mantle.ngrok.com/components/multi-select#multiselectempty\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 * {matches.length === 0 && (\n * <MultiSelect.Empty>No results found</MultiSelect.Empty>\n * )}\n * </MultiSelect.Content>\n * </MultiSelect.Root>\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 * @see https://mantle.ngrok.com/components/multi-select#multiselectcontentfooter\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.ContentFooter>\n * <p>Upgrade to unlock more options.</p>\n * <Button>Upgrade</Button>\n * </MultiSelect.ContentFooter>\n * </MultiSelect.Content>\n * </MultiSelect.Root>\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 * Use MultiSelect when the user can choose multiple values from a list, with selected\n * items rendered as removable tags/chips. For single selection, use Combobox (with search)\n * or Select (without).\n *\n * @see https://mantle.ngrok.com/components/multi-select\n * @see https://www.w3.org/WAI/ARIA/apg/patterns/combobox/\n * @see https://ariakit.org/components/combobox\n *\n * @example\n * Composition:\n * ```\n * MultiSelect.Root\n * ├── MultiSelect.Trigger\n * │ ├── MultiSelect.TagValues\n * │ └── MultiSelect.Input\n * └── MultiSelect.Content\n * ├── MultiSelect.Group\n * │ ├── MultiSelect.GroupLabel\n * │ ├── MultiSelect.GroupDescription\n * │ └── MultiSelect.Item\n * ├── MultiSelect.Separator\n * ├── MultiSelect.Empty\n * └── MultiSelect.ContentFooter\n * ```\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 * Use MultiSelect when the user can choose multiple values from a list, with selected\n\t * items rendered as removable tags/chips. For single selection, use Combobox (with search)\n\t * or Select (without).\n\t *\n\t * @see https://mantle.ngrok.com/components/multi-select#multiselectroot\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 * @see https://mantle.ngrok.com/components/multi-select#multiselecttrigger\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\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 * @see https://mantle.ngrok.com/components/multi-select#multiselecttagvalues\n\t *\n\t * @example\n\t * ```tsx\n\t * <MultiSelect.Root>\n\t * <MultiSelect.Trigger>\n\t * <MultiSelect.TagValues lockedValues={[\"global\"]} />\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\t * @example\n\t * Custom tags via children render function — `locked` is forwarded via props.\n\t * ```tsx\n\t * <MultiSelect.Root>\n\t * <MultiSelect.Trigger>\n\t * <MultiSelect.TagValues lockedValues={[\"global\"]}>\n\t * {(props) => <MultiSelect.Tag key={props.value} {...props} />}\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\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 * @see https://mantle.ngrok.com/components/multi-select#multiselectinput\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\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 * @see https://mantle.ngrok.com/components/multi-select#multiselecttag\n\t *\n\t * @example\n\t * ```tsx\n\t * <MultiSelect.Root>\n\t * <MultiSelect.Trigger>\n\t * <MultiSelect.TagValues>\n\t * {(props) => <MultiSelect.Tag key={props.value} {...props} />}\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\tTag,\n\t/**\n\t * Renders a popover that contains multi-select content.\n\t *\n\t * @see https://mantle.ngrok.com/components/multi-select#multiselectcontent\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.Item value=\"banana\">Banana</MultiSelect.Item>\n\t * </MultiSelect.Content>\n\t * </MultiSelect.Root>\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 * @see https://mantle.ngrok.com/components/multi-select#multiselectcontentfooter\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.ContentFooter>\n\t * <p>Upgrade to unlock more options.</p>\n\t * </MultiSelect.ContentFooter>\n\t * </MultiSelect.Content>\n\t * </MultiSelect.Root>\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 * @see https://mantle.ngrok.com/components/multi-select#multiselectitem\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.Item value=\"banana\">Banana</MultiSelect.Item>\n\t * </MultiSelect.Content>\n\t * </MultiSelect.Root>\n\t * ```\n\t */\n\tItem,\n\t/**\n\t * Renders a group for MultiSelect.Item elements.\n\t *\n\t * @see https://mantle.ngrok.com/components/multi-select#multiselectgroup\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.Group>\n\t * <MultiSelect.GroupLabel>Fruits</MultiSelect.GroupLabel>\n\t * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n\t * </MultiSelect.Group>\n\t * </MultiSelect.Content>\n\t * </MultiSelect.Root>\n\t * ```\n\t */\n\tGroup,\n\t/**\n\t * Renders a label in a multi-select group.\n\t *\n\t * @see https://mantle.ngrok.com/components/multi-select#multiselectgrouplabel\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.Group>\n\t * <MultiSelect.GroupLabel>Fruits</MultiSelect.GroupLabel>\n\t * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n\t * </MultiSelect.Group>\n\t * </MultiSelect.Content>\n\t * </MultiSelect.Root>\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 * @see https://mantle.ngrok.com/components/multi-select#multiselectgroupdescription\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 regions...\" />\n\t * </MultiSelect.Trigger>\n\t * <MultiSelect.Content>\n\t * <MultiSelect.Group>\n\t * <MultiSelect.GroupLabel>Regional Aliases</MultiSelect.GroupLabel>\n\t * <MultiSelect.GroupDescription>\n\t * Include all points of presence within the region.\n\t * </MultiSelect.GroupDescription>\n\t * <MultiSelect.Item value=\"global\">global</MultiSelect.Item>\n\t * </MultiSelect.Group>\n\t * </MultiSelect.Content>\n\t * </MultiSelect.Root>\n\t * ```\n\t */\n\tGroupDescription,\n\t/**\n\t * Renders a separator between items or groups.\n\t *\n\t * @see https://mantle.ngrok.com/components/multi-select#multiselectseparator\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.Group>\n\t * <MultiSelect.Item value=\"apple\">Apple</MultiSelect.Item>\n\t * </MultiSelect.Group>\n\t * <MultiSelect.Separator />\n\t * <MultiSelect.Group>\n\t * <MultiSelect.Item value=\"carrot\">Carrot</MultiSelect.Item>\n\t * </MultiSelect.Group>\n\t * </MultiSelect.Content>\n\t * </MultiSelect.Root>\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 * @see https://mantle.ngrok.com/components/multi-select#multiselectempty\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 * {matches.length === 0 && (\n\t * <MultiSelect.Empty>No results found</MultiSelect.Empty>\n\t * )}\n\t * </MultiSelect.Content>\n\t * </MultiSelect.Root>\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,6 +1,5 @@
1
- import { t as WithAsChild } from "./as-child-CpZKMqTE.js";
2
- import { o as WithValidation } from "./validation-CBSOmooP.js";
3
- import * as _$react from "react";
1
+ import { t as WithAsChild } from "./as-child-uN_018tj.js";
2
+ import { o as WithValidation } from "./validation-xyX_6kph.js";
4
3
  import { ComponentProps, ReactNode } from "react";
5
4
  import { OTPInput, REGEXP_ONLY_CHARS, REGEXP_ONLY_DIGITS, REGEXP_ONLY_DIGITS_AND_CHARS } from "input-otp";
6
5
 
@@ -88,7 +87,7 @@ declare const OtpInput: {
88
87
  * </OtpInput.Root>
89
88
  * ```
90
89
  */
91
- readonly Root: _$react.ForwardRefExoticComponent<Omit<OtpInputRootProps, "ref"> & _$react.RefAttributes<HTMLInputElement>>;
90
+ readonly Root: import("react").ForwardRefExoticComponent<Omit<OtpInputRootProps, "ref"> & import("react").RefAttributes<HTMLInputElement>>;
92
91
  /**
93
92
  * Groups one or more `OtpInput.Slot` parts into a visually-connected
94
93
  * segment with shared rounded corners and joined borders.
@@ -112,7 +111,7 @@ declare const OtpInput: {
112
111
  * </OtpInput.Root>
113
112
  * ```
114
113
  */
115
- readonly Group: _$react.ForwardRefExoticComponent<Omit<OtpInputGroupProps, "ref"> & _$react.RefAttributes<HTMLDivElement>>;
114
+ readonly Group: import("react").ForwardRefExoticComponent<Omit<OtpInputGroupProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
116
115
  /**
117
116
  * A single character slot. Must be rendered inside an `OtpInput.Root`.
118
117
  * Reads its character, active state, and fake caret position from the
@@ -137,7 +136,7 @@ declare const OtpInput: {
137
136
  * </OtpInput.Root>
138
137
  * ```
139
138
  */
140
- readonly Slot: _$react.ForwardRefExoticComponent<Omit<OtpInputSlotProps, "ref"> & _$react.RefAttributes<HTMLDivElement>>;
139
+ readonly Slot: import("react").ForwardRefExoticComponent<Omit<OtpInputSlotProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
141
140
  /**
142
141
  * A visual separator between two `OtpInput.Group` segments. Renders a
143
142
  * minus icon by default; pass `children` to override.
@@ -161,7 +160,7 @@ declare const OtpInput: {
161
160
  * </OtpInput.Root>
162
161
  * ```
163
162
  */
164
- readonly Separator: _$react.ForwardRefExoticComponent<Omit<OtpInputSeparatorProps, "ref"> & _$react.RefAttributes<HTMLDivElement>>;
163
+ readonly Separator: import("react").ForwardRefExoticComponent<Omit<OtpInputSeparatorProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
165
164
  };
166
165
  //#endregion
167
166
  export { OtpInput, REGEXP_ONLY_CHARS, REGEXP_ONLY_DIGITS, REGEXP_ONLY_DIGITS_AND_CHARS };
package/dist/otp-input.js CHANGED
@@ -1,2 +1,2 @@
1
- import{t as e}from"./cx-D1HYnpvA.js";import{t}from"./types-884RJJqm.js";import{t as n}from"./slot-D_ZUrdEW.js";import{a as r,r as i}from"./validation-BYME8rWN.js";import{t as a}from"./field-context-B7Z1cmZW.js";import{forwardRef as o,useContext as s}from"react";import{jsx as c,jsxs as l}from"react/jsx-runtime";import{MinusIcon as u}from"@phosphor-icons/react/Minus";import{OTPInput as d,OTPInputContext as f,REGEXP_ONLY_CHARS as p,REGEXP_ONLY_DIGITS as m,REGEXP_ONLY_DIGITS_AND_CHARS as h}from"input-otp";const g={error:`danger`,success:`success`,warning:`warning`},_=e=>`var(--color-${e}-600)`,v=e=>`var(--ring-color-focus-${e})`,y=({totalActive:e,total:t})=>e===0?`idle`:e===1?`caret`:e===t?`all`:`range`,b=({children:e,validation:n})=>{let r=s(f),i=r.slots.length,a=y({totalActive:r.slots.reduce((e,t)=>e+ +!!t.isActive,0),total:i}),o=n?g[n]:void 0,l=o?t({"--otp-validation-border":_(o),"--otp-validation-ring":v(o)}):void 0;return c(`div`,{className:`group/otp contents`,"data-otp-state":a,"data-validation":n||void 0,style:l,children:e})},x=o(({"aria-invalid":t,children:n,className:o,containerClassName:l,validation:u,...f},p)=>{let m=r(),h=s(a),{ariaInvalid:g,validation:_}=i({"aria-invalid":t,defaultAriaInvalid:!1,validation:u??m});return c(d,{ref:p,"aria-invalid":g,"data-slot":`otp-input`,containerClassName:e(`flex items-center gap-2 has-disabled:opacity-50`,l),className:e(`disabled:cursor-not-allowed`,o),...f,...h?{"aria-describedby":h[`aria-describedby`],"aria-errormessage":h[`aria-errormessage`],id:h.id,name:h.name}:void 0,children:c(b,{validation:_,children:n})})});x.displayName=`OtpInput`;const S=o(({asChild:t,children:r,className:i,...a},o)=>c(t?n:`div`,{ref:o,"data-slot":`otp-input-group`,className:e(`relative flex items-center rounded-md`,`has-[[data-active]~[data-active]]:ring-focus-accent has-[[data-active]~[data-active]]:ring-4`,`group-data-validation/otp:has-[[data-active]~[data-active]]:ring-(--otp-validation-ring)`,i),...a,children:r}));S.displayName=`OtpInputGroup`;const C=o(({className:t,index:n,...r},i)=>{let a=s(f).slots[n],o=a?.char??null,u=a?.hasFakeCaret??!1;return l(`div`,{ref:i,"data-slot":`otp-input-slot`,"data-active":a?.isActive??!1?``:void 0,className:e(`border-form bg-form text-strong relative flex h-10 w-10 items-center justify-center border-y border-r text-sm shadow-sm outline-hidden transition-all duration-150 ease-out`,`first:rounded-l-md first:border-l last:rounded-r-md`,`[&:has(+[data-active])]:group-data-[otp-state=caret]/otp:border-r-transparent`,`data-active:group-data-[otp-state=caret]/otp:border-accent-600`,`data-active:group-data-[otp-state=caret]/otp:border-l`,`data-active:group-data-[otp-state=caret]/otp:ring-focus-accent`,`data-active:group-data-[otp-state=caret]/otp:z-20`,`data-active:group-data-[otp-state=caret]/otp:ring-4`,`group-data-[otp-state=all]/otp:border-accent-600`,`group-data-validation/otp:border-y-(--otp-validation-border)`,`group-data-validation/otp:first:border-l-(--otp-validation-border)`,`group-data-validation/otp:last:border-r-(--otp-validation-border)`,`group-data-validation/otp:data-active:group-data-[otp-state=caret]/otp:border-(--otp-validation-border)`,`group-data-validation/otp:data-active:group-data-[otp-state=caret]/otp:ring-(--otp-validation-ring)`,`group-data-validation/otp:group-data-[otp-state=all]/otp:border-(--otp-validation-border)`,t),...r,children:[o,u&&c(`div`,{className:`pointer-events-none absolute inset-0 flex items-center justify-center`,children:c(`div`,{className:`bg-strong h-4 w-px animate-pulse`})})]})});C.displayName=`OtpInputSlot`;const w=o(({asChild:t,children:r,className:i,semantic:a=!1,...o},s)=>{let l=t?n:`div`,d=a?{role:`separator`}:{"aria-hidden":!0,role:`none`};return c(l,{ref:s,"data-slot":`otp-input-separator`,className:e(`text-muted flex items-center`,i),...d,...o,children:r??c(u,{weight:`bold`})})});w.displayName=`OtpInputSeparator`;const T={Root:x,Group:S,Slot:C,Separator:w};export{T as OtpInput,p as REGEXP_ONLY_CHARS,m as REGEXP_ONLY_DIGITS,h as REGEXP_ONLY_DIGITS_AND_CHARS};
1
+ import{t as e}from"./cx-CBSnSC36.js";import{t}from"./types-D85fCNV3.js";import{t as n}from"./slot-CV5fmqFr.js";import{a as r,r as i}from"./validation-DCyx-ceH.js";import{t as a}from"./field-context-4k1kI7Bo.js";import{forwardRef as o,useContext as s}from"react";import{jsx as c,jsxs as l}from"react/jsx-runtime";import{MinusIcon as u}from"@phosphor-icons/react/Minus";import{OTPInput as d,OTPInputContext as f,REGEXP_ONLY_CHARS as p,REGEXP_ONLY_DIGITS as m,REGEXP_ONLY_DIGITS_AND_CHARS as h}from"input-otp";const g={error:`danger`,success:`success`,warning:`warning`},_=e=>`var(--color-${e}-600)`,v=e=>`var(--ring-color-focus-${e})`,y=({totalActive:e,total:t})=>e===0?`idle`:e===1?`caret`:e===t?`all`:`range`,b=({children:e,validation:n})=>{let r=s(f),i=r.slots.length,a=y({totalActive:r.slots.reduce((e,t)=>e+ +!!t.isActive,0),total:i}),o=n?g[n]:void 0,l=o?t({"--otp-validation-border":_(o),"--otp-validation-ring":v(o)}):void 0;return c(`div`,{className:`group/otp contents`,"data-otp-state":a,"data-validation":n||void 0,style:l,children:e})},x=o(({"aria-invalid":t,children:n,className:o,containerClassName:l,validation:u,...f},p)=>{let m=r(),h=s(a),{ariaInvalid:g,validation:_}=i({"aria-invalid":t,defaultAriaInvalid:!1,validation:u??m});return c(d,{ref:p,"aria-invalid":g,"data-slot":`otp-input`,containerClassName:e(`flex items-center gap-2 has-disabled:opacity-50`,l),className:e(`disabled:cursor-not-allowed`,o),...f,...h?{"aria-describedby":h[`aria-describedby`],"aria-errormessage":h[`aria-errormessage`],id:h.id,name:h.name}:void 0,children:c(b,{validation:_,children:n})})});x.displayName=`OtpInput`;const S=o(({asChild:t,children:r,className:i,...a},o)=>c(t?n:`div`,{ref:o,"data-slot":`otp-input-group`,className:e(`relative flex items-center rounded-md`,`has-[[data-active]~[data-active]]:ring-focus-accent has-[[data-active]~[data-active]]:ring-4`,`group-data-validation/otp:has-[[data-active]~[data-active]]:ring-(--otp-validation-ring)`,i),...a,children:r}));S.displayName=`OtpInputGroup`;const C=o(({className:t,index:n,...r},i)=>{let a=s(f).slots[n],o=a?.char??null,u=a?.hasFakeCaret??!1;return l(`div`,{ref:i,"data-slot":`otp-input-slot`,"data-active":a?.isActive??!1?``:void 0,className:e(`border-form bg-form text-strong relative flex h-10 w-10 items-center justify-center border-y border-r text-sm shadow-sm outline-hidden transition-all duration-150 ease-out`,`first:rounded-l-md first:border-l last:rounded-r-md`,`[&:has(+[data-active])]:group-data-[otp-state=caret]/otp:border-r-transparent`,`data-active:group-data-[otp-state=caret]/otp:border-accent-600`,`data-active:group-data-[otp-state=caret]/otp:border-l`,`data-active:group-data-[otp-state=caret]/otp:ring-focus-accent`,`data-active:group-data-[otp-state=caret]/otp:z-20`,`data-active:group-data-[otp-state=caret]/otp:ring-4`,`group-data-[otp-state=all]/otp:border-accent-600`,`group-data-validation/otp:border-y-(--otp-validation-border)`,`group-data-validation/otp:first:border-l-(--otp-validation-border)`,`group-data-validation/otp:last:border-r-(--otp-validation-border)`,`group-data-validation/otp:data-active:group-data-[otp-state=caret]/otp:border-(--otp-validation-border)`,`group-data-validation/otp:data-active:group-data-[otp-state=caret]/otp:ring-(--otp-validation-ring)`,`group-data-validation/otp:group-data-[otp-state=all]/otp:border-(--otp-validation-border)`,t),...r,children:[o,u&&c(`div`,{className:`pointer-events-none absolute inset-0 flex items-center justify-center`,children:c(`div`,{className:`bg-strong h-4 w-px animate-pulse`})})]})});C.displayName=`OtpInputSlot`;const w=o(({asChild:t,children:r,className:i,semantic:a=!1,...o},s)=>{let l=t?n:`div`,d=a?{role:`separator`}:{"aria-hidden":!0,role:`none`};return c(l,{ref:s,"data-slot":`otp-input-separator`,className:e(`text-muted flex items-center`,i),...d,...o,children:r??c(u,{weight:`bold`})})});w.displayName=`OtpInputSeparator`;const T={Root:x,Group:S,Slot:C,Separator:w};export{T as OtpInput,p as REGEXP_ONLY_CHARS,m as REGEXP_ONLY_DIGITS,h as REGEXP_ONLY_DIGITS_AND_CHARS};
2
2
  //# sourceMappingURL=otp-input.js.map