@inui/design-system 0.0.0-stage → 1.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (312) hide show
  1. package/README.md +360 -2
  2. package/dist/components/ui/accordion.d.ts +44 -0
  3. package/dist/components/ui/accordion.d.ts.map +1 -0
  4. package/dist/components/ui/accordion.js +86 -0
  5. package/dist/components/ui/accordion.js.map +1 -0
  6. package/dist/components/ui/ai-avatar.d.ts +46 -0
  7. package/dist/components/ui/ai-avatar.d.ts.map +1 -0
  8. package/dist/components/ui/ai-avatar.js +43 -0
  9. package/dist/components/ui/ai-avatar.js.map +1 -0
  10. package/dist/components/ui/ai-label.d.ts +118 -0
  11. package/dist/components/ui/ai-label.d.ts.map +1 -0
  12. package/dist/components/ui/ai-label.js +184 -0
  13. package/dist/components/ui/ai-label.js.map +1 -0
  14. package/dist/components/ui/ai-sparkle.d.ts +91 -0
  15. package/dist/components/ui/ai-sparkle.d.ts.map +1 -0
  16. package/dist/components/ui/ai-sparkle.js +200 -0
  17. package/dist/components/ui/ai-sparkle.js.map +1 -0
  18. package/dist/components/ui/alert-dialog.d.ts +79 -0
  19. package/dist/components/ui/alert-dialog.d.ts.map +1 -0
  20. package/dist/components/ui/alert-dialog.js +147 -0
  21. package/dist/components/ui/alert-dialog.js.map +1 -0
  22. package/dist/components/ui/alert.d.ts +71 -0
  23. package/dist/components/ui/alert.d.ts.map +1 -0
  24. package/dist/components/ui/alert.js +108 -0
  25. package/dist/components/ui/alert.js.map +1 -0
  26. package/dist/components/ui/aspect-ratio.d.ts +30 -0
  27. package/dist/components/ui/aspect-ratio.d.ts.map +1 -0
  28. package/dist/components/ui/aspect-ratio.js +40 -0
  29. package/dist/components/ui/aspect-ratio.js.map +1 -0
  30. package/dist/components/ui/attachment.d.ts +74 -0
  31. package/dist/components/ui/attachment.d.ts.map +1 -0
  32. package/dist/components/ui/attachment.js +142 -0
  33. package/dist/components/ui/attachment.js.map +1 -0
  34. package/dist/components/ui/avatar.d.ts +82 -0
  35. package/dist/components/ui/avatar.d.ts.map +1 -0
  36. package/dist/components/ui/avatar.js +123 -0
  37. package/dist/components/ui/avatar.js.map +1 -0
  38. package/dist/components/ui/badge.d.ts +130 -0
  39. package/dist/components/ui/badge.d.ts.map +1 -0
  40. package/dist/components/ui/badge.js +226 -0
  41. package/dist/components/ui/badge.js.map +1 -0
  42. package/dist/components/ui/breadcrumb.d.ts +43 -0
  43. package/dist/components/ui/breadcrumb.d.ts.map +1 -0
  44. package/dist/components/ui/breadcrumb.js +98 -0
  45. package/dist/components/ui/breadcrumb.js.map +1 -0
  46. package/dist/components/ui/browser-tabs.d.ts +218 -0
  47. package/dist/components/ui/browser-tabs.d.ts.map +1 -0
  48. package/dist/components/ui/browser-tabs.js +528 -0
  49. package/dist/components/ui/browser-tabs.js.map +1 -0
  50. package/dist/components/ui/bubble.d.ts +80 -0
  51. package/dist/components/ui/bubble.d.ts.map +1 -0
  52. package/dist/components/ui/bubble.js +235 -0
  53. package/dist/components/ui/bubble.js.map +1 -0
  54. package/dist/components/ui/button-group.d.ts +60 -0
  55. package/dist/components/ui/button-group.d.ts.map +1 -0
  56. package/dist/components/ui/button-group.js +89 -0
  57. package/dist/components/ui/button-group.js.map +1 -0
  58. package/dist/components/ui/button.d.ts +157 -0
  59. package/dist/components/ui/button.d.ts.map +1 -0
  60. package/dist/components/ui/button.js +144 -0
  61. package/dist/components/ui/button.js.map +1 -0
  62. package/dist/components/ui/calendar.d.ts +57 -0
  63. package/dist/components/ui/calendar.d.ts.map +1 -0
  64. package/dist/components/ui/calendar.js +163 -0
  65. package/dist/components/ui/calendar.js.map +1 -0
  66. package/dist/components/ui/card.d.ts +96 -0
  67. package/dist/components/ui/card.d.ts.map +1 -0
  68. package/dist/components/ui/card.js +131 -0
  69. package/dist/components/ui/card.js.map +1 -0
  70. package/dist/components/ui/carousel.d.ts +86 -0
  71. package/dist/components/ui/carousel.d.ts.map +1 -0
  72. package/dist/components/ui/carousel.js +207 -0
  73. package/dist/components/ui/carousel.js.map +1 -0
  74. package/dist/components/ui/checkbox.d.ts +54 -0
  75. package/dist/components/ui/checkbox.d.ts.map +1 -0
  76. package/dist/components/ui/checkbox.js +78 -0
  77. package/dist/components/ui/checkbox.js.map +1 -0
  78. package/dist/components/ui/collapsible.d.ts +45 -0
  79. package/dist/components/ui/collapsible.d.ts.map +1 -0
  80. package/dist/components/ui/collapsible.js +65 -0
  81. package/dist/components/ui/collapsible.js.map +1 -0
  82. package/dist/components/ui/combobox.d.ts +111 -0
  83. package/dist/components/ui/combobox.d.ts.map +1 -0
  84. package/dist/components/ui/combobox.js +264 -0
  85. package/dist/components/ui/combobox.js.map +1 -0
  86. package/dist/components/ui/command.d.ts +71 -0
  87. package/dist/components/ui/command.d.ts.map +1 -0
  88. package/dist/components/ui/command.js +133 -0
  89. package/dist/components/ui/command.js.map +1 -0
  90. package/dist/components/ui/context-menu.d.ts +70 -0
  91. package/dist/components/ui/context-menu.d.ts.map +1 -0
  92. package/dist/components/ui/context-menu.js +163 -0
  93. package/dist/components/ui/context-menu.js.map +1 -0
  94. package/dist/components/ui/count-badge.d.ts +40 -0
  95. package/dist/components/ui/count-badge.d.ts.map +1 -0
  96. package/dist/components/ui/count-badge.js +43 -0
  97. package/dist/components/ui/count-badge.js.map +1 -0
  98. package/dist/components/ui/data-table.d.ts +1026 -0
  99. package/dist/components/ui/data-table.d.ts.map +1 -0
  100. package/dist/components/ui/data-table.js +3423 -0
  101. package/dist/components/ui/data-table.js.map +1 -0
  102. package/dist/components/ui/dialog.d.ts +73 -0
  103. package/dist/components/ui/dialog.d.ts.map +1 -0
  104. package/dist/components/ui/dialog.js +145 -0
  105. package/dist/components/ui/dialog.js.map +1 -0
  106. package/dist/components/ui/direction.d.ts +35 -0
  107. package/dist/components/ui/direction.d.ts.map +1 -0
  108. package/dist/components/ui/direction.js +35 -0
  109. package/dist/components/ui/direction.js.map +1 -0
  110. package/dist/components/ui/drawer.d.ts +53 -0
  111. package/dist/components/ui/drawer.d.ts.map +1 -0
  112. package/dist/components/ui/drawer.js +115 -0
  113. package/dist/components/ui/drawer.js.map +1 -0
  114. package/dist/components/ui/dropdown-menu.d.ts +75 -0
  115. package/dist/components/ui/dropdown-menu.d.ts.map +1 -0
  116. package/dist/components/ui/dropdown-menu.js +173 -0
  117. package/dist/components/ui/dropdown-menu.js.map +1 -0
  118. package/dist/components/ui/dropzone.d.ts +141 -0
  119. package/dist/components/ui/dropzone.d.ts.map +1 -0
  120. package/dist/components/ui/dropzone.js +257 -0
  121. package/dist/components/ui/dropzone.js.map +1 -0
  122. package/dist/components/ui/empty.d.ts +94 -0
  123. package/dist/components/ui/empty.d.ts.map +1 -0
  124. package/dist/components/ui/empty.js +149 -0
  125. package/dist/components/ui/empty.js.map +1 -0
  126. package/dist/components/ui/field.d.ts +122 -0
  127. package/dist/components/ui/field.d.ts.map +1 -0
  128. package/dist/components/ui/field.js +254 -0
  129. package/dist/components/ui/field.js.map +1 -0
  130. package/dist/components/ui/hover-card.d.ts +51 -0
  131. package/dist/components/ui/hover-card.d.ts.map +1 -0
  132. package/dist/components/ui/hover-card.js +101 -0
  133. package/dist/components/ui/hover-card.js.map +1 -0
  134. package/dist/components/ui/input-group.d.ts +62 -0
  135. package/dist/components/ui/input-group.d.ts.map +1 -0
  136. package/dist/components/ui/input-group.js +115 -0
  137. package/dist/components/ui/input-group.js.map +1 -0
  138. package/dist/components/ui/input-otp.d.ts +52 -0
  139. package/dist/components/ui/input-otp.d.ts.map +1 -0
  140. package/dist/components/ui/input-otp.js +89 -0
  141. package/dist/components/ui/input-otp.js.map +1 -0
  142. package/dist/components/ui/input.d.ts +47 -0
  143. package/dist/components/ui/input.d.ts.map +1 -0
  144. package/dist/components/ui/input.js +47 -0
  145. package/dist/components/ui/input.js.map +1 -0
  146. package/dist/components/ui/item.d.ts +74 -0
  147. package/dist/components/ui/item.d.ts.map +1 -0
  148. package/dist/components/ui/item.js +176 -0
  149. package/dist/components/ui/item.js.map +1 -0
  150. package/dist/components/ui/kbd.d.ts +41 -0
  151. package/dist/components/ui/kbd.d.ts.map +1 -0
  152. package/dist/components/ui/kbd.js +58 -0
  153. package/dist/components/ui/kbd.js.map +1 -0
  154. package/dist/components/ui/key-value-pair.d.ts +56 -0
  155. package/dist/components/ui/key-value-pair.d.ts.map +1 -0
  156. package/dist/components/ui/key-value-pair.js +110 -0
  157. package/dist/components/ui/key-value-pair.js.map +1 -0
  158. package/dist/components/ui/label.d.ts +83 -0
  159. package/dist/components/ui/label.d.ts.map +1 -0
  160. package/dist/components/ui/label.js +85 -0
  161. package/dist/components/ui/label.js.map +1 -0
  162. package/dist/components/ui/marker.d.ts +54 -0
  163. package/dist/components/ui/marker.d.ts.map +1 -0
  164. package/dist/components/ui/marker.js +79 -0
  165. package/dist/components/ui/marker.js.map +1 -0
  166. package/dist/components/ui/menubar.d.ts +72 -0
  167. package/dist/components/ui/menubar.d.ts.map +1 -0
  168. package/dist/components/ui/menubar.js +174 -0
  169. package/dist/components/ui/menubar.js.map +1 -0
  170. package/dist/components/ui/message-scroller.d.ts +53 -0
  171. package/dist/components/ui/message-scroller.d.ts.map +1 -0
  172. package/dist/components/ui/message-scroller.js +95 -0
  173. package/dist/components/ui/message-scroller.js.map +1 -0
  174. package/dist/components/ui/message.d.ts +63 -0
  175. package/dist/components/ui/message.d.ts.map +1 -0
  176. package/dist/components/ui/message.js +92 -0
  177. package/dist/components/ui/message.js.map +1 -0
  178. package/dist/components/ui/meta-list.d.ts +55 -0
  179. package/dist/components/ui/meta-list.d.ts.map +1 -0
  180. package/dist/components/ui/meta-list.js +75 -0
  181. package/dist/components/ui/meta-list.js.map +1 -0
  182. package/dist/components/ui/native-select.d.ts +51 -0
  183. package/dist/components/ui/native-select.d.ts.map +1 -0
  184. package/dist/components/ui/native-select.js +75 -0
  185. package/dist/components/ui/native-select.js.map +1 -0
  186. package/dist/components/ui/navigation-menu.d.ts +56 -0
  187. package/dist/components/ui/navigation-menu.d.ts.map +1 -0
  188. package/dist/components/ui/navigation-menu.js +116 -0
  189. package/dist/components/ui/navigation-menu.js.map +1 -0
  190. package/dist/components/ui/page-header.d.ts +223 -0
  191. package/dist/components/ui/page-header.d.ts.map +1 -0
  192. package/dist/components/ui/page-header.js +233 -0
  193. package/dist/components/ui/page-header.js.map +1 -0
  194. package/dist/components/ui/pagination.d.ts +68 -0
  195. package/dist/components/ui/pagination.d.ts.map +1 -0
  196. package/dist/components/ui/pagination.js +145 -0
  197. package/dist/components/ui/pagination.js.map +1 -0
  198. package/dist/components/ui/popover.d.ts +61 -0
  199. package/dist/components/ui/popover.d.ts.map +1 -0
  200. package/dist/components/ui/popover.js +144 -0
  201. package/dist/components/ui/popover.js.map +1 -0
  202. package/dist/components/ui/progress.d.ts +35 -0
  203. package/dist/components/ui/progress.d.ts.map +1 -0
  204. package/dist/components/ui/progress.js +46 -0
  205. package/dist/components/ui/progress.js.map +1 -0
  206. package/dist/components/ui/questionnaire.d.ts +92 -0
  207. package/dist/components/ui/questionnaire.d.ts.map +1 -0
  208. package/dist/components/ui/questionnaire.js +277 -0
  209. package/dist/components/ui/questionnaire.js.map +1 -0
  210. package/dist/components/ui/radio-group.d.ts +50 -0
  211. package/dist/components/ui/radio-group.d.ts.map +1 -0
  212. package/dist/components/ui/radio-group.js +65 -0
  213. package/dist/components/ui/radio-group.js.map +1 -0
  214. package/dist/components/ui/resizable.d.ts +44 -0
  215. package/dist/components/ui/resizable.d.ts.map +1 -0
  216. package/dist/components/ui/resizable.js +73 -0
  217. package/dist/components/ui/resizable.js.map +1 -0
  218. package/dist/components/ui/scroll-area.d.ts +55 -0
  219. package/dist/components/ui/scroll-area.d.ts.map +1 -0
  220. package/dist/components/ui/scroll-area.js +72 -0
  221. package/dist/components/ui/scroll-area.js.map +1 -0
  222. package/dist/components/ui/select.d.ts +274 -0
  223. package/dist/components/ui/select.d.ts.map +1 -0
  224. package/dist/components/ui/select.js +609 -0
  225. package/dist/components/ui/select.js.map +1 -0
  226. package/dist/components/ui/separator.d.ts +31 -0
  227. package/dist/components/ui/separator.d.ts.map +1 -0
  228. package/dist/components/ui/separator.js +38 -0
  229. package/dist/components/ui/separator.js.map +1 -0
  230. package/dist/components/ui/sheet.d.ts +59 -0
  231. package/dist/components/ui/sheet.d.ts.map +1 -0
  232. package/dist/components/ui/sheet.js +128 -0
  233. package/dist/components/ui/sheet.js.map +1 -0
  234. package/dist/components/ui/sidebar.d.ts +166 -0
  235. package/dist/components/ui/sidebar.d.ts.map +1 -0
  236. package/dist/components/ui/sidebar.js +512 -0
  237. package/dist/components/ui/sidebar.js.map +1 -0
  238. package/dist/components/ui/skeleton.d.ts +35 -0
  239. package/dist/components/ui/skeleton.d.ts.map +1 -0
  240. package/dist/components/ui/skeleton.js +46 -0
  241. package/dist/components/ui/skeleton.js.map +1 -0
  242. package/dist/components/ui/slider.d.ts +39 -0
  243. package/dist/components/ui/slider.d.ts.map +1 -0
  244. package/dist/components/ui/slider.js +75 -0
  245. package/dist/components/ui/slider.js.map +1 -0
  246. package/dist/components/ui/sonner.d.ts +56 -0
  247. package/dist/components/ui/sonner.d.ts.map +1 -0
  248. package/dist/components/ui/sonner.js +96 -0
  249. package/dist/components/ui/sonner.js.map +1 -0
  250. package/dist/components/ui/spinner.d.ts +37 -0
  251. package/dist/components/ui/spinner.d.ts.map +1 -0
  252. package/dist/components/ui/spinner.js +51 -0
  253. package/dist/components/ui/spinner.js.map +1 -0
  254. package/dist/components/ui/stepper.d.ts +84 -0
  255. package/dist/components/ui/stepper.d.ts.map +1 -0
  256. package/dist/components/ui/stepper.js +145 -0
  257. package/dist/components/ui/stepper.js.map +1 -0
  258. package/dist/components/ui/switch.d.ts +36 -0
  259. package/dist/components/ui/switch.d.ts.map +1 -0
  260. package/dist/components/ui/switch.js +44 -0
  261. package/dist/components/ui/switch.js.map +1 -0
  262. package/dist/components/ui/table.d.ts +80 -0
  263. package/dist/components/ui/table.d.ts.map +1 -0
  264. package/dist/components/ui/table.js +130 -0
  265. package/dist/components/ui/table.js.map +1 -0
  266. package/dist/components/ui/tabs.d.ts +87 -0
  267. package/dist/components/ui/tabs.d.ts.map +1 -0
  268. package/dist/components/ui/tabs.js +128 -0
  269. package/dist/components/ui/tabs.js.map +1 -0
  270. package/dist/components/ui/textarea.d.ts +35 -0
  271. package/dist/components/ui/textarea.d.ts.map +1 -0
  272. package/dist/components/ui/textarea.js +38 -0
  273. package/dist/components/ui/textarea.js.map +1 -0
  274. package/dist/components/ui/time-picker.d.ts +58 -0
  275. package/dist/components/ui/time-picker.d.ts.map +1 -0
  276. package/dist/components/ui/time-picker.js +188 -0
  277. package/dist/components/ui/time-picker.js.map +1 -0
  278. package/dist/components/ui/toggle-group.d.ts +52 -0
  279. package/dist/components/ui/toggle-group.d.ts.map +1 -0
  280. package/dist/components/ui/toggle-group.js +94 -0
  281. package/dist/components/ui/toggle-group.js.map +1 -0
  282. package/dist/components/ui/toggle.d.ts +50 -0
  283. package/dist/components/ui/toggle.d.ts.map +1 -0
  284. package/dist/components/ui/toggle.js +70 -0
  285. package/dist/components/ui/toggle.js.map +1 -0
  286. package/dist/components/ui/tooltip.d.ts +51 -0
  287. package/dist/components/ui/tooltip.d.ts.map +1 -0
  288. package/dist/components/ui/tooltip.js +78 -0
  289. package/dist/components/ui/tooltip.js.map +1 -0
  290. package/dist/hooks/use-dark-mode.d.ts +2 -0
  291. package/dist/hooks/use-dark-mode.d.ts.map +1 -0
  292. package/dist/hooks/use-dark-mode.js +36 -0
  293. package/dist/hooks/use-dark-mode.js.map +1 -0
  294. package/dist/hooks/use-mobile.d.ts +2 -0
  295. package/dist/hooks/use-mobile.d.ts.map +1 -0
  296. package/dist/hooks/use-mobile.js +20 -0
  297. package/dist/hooks/use-mobile.js.map +1 -0
  298. package/dist/index.d.ts +88 -0
  299. package/dist/index.d.ts.map +1 -0
  300. package/dist/index.js +77 -0
  301. package/dist/lib/scope.d.ts +64 -0
  302. package/dist/lib/scope.d.ts.map +1 -0
  303. package/dist/lib/scope.js +74 -0
  304. package/dist/lib/scope.js.map +1 -0
  305. package/dist/lib/utils.d.ts +3 -0
  306. package/dist/lib/utils.d.ts.map +1 -0
  307. package/dist/lib/utils.js +11 -0
  308. package/dist/lib/utils.js.map +1 -0
  309. package/dist/styles.css +2 -0
  310. package/dist/theme-tokens.css +537 -0
  311. package/dist/theme.css +417 -0
  312. package/package.json +103 -3
@@ -0,0 +1,609 @@
1
+ "use client";
2
+ import { cn } from "../../lib/utils.js";
3
+ import { getPortalContainer } from "../../lib/scope.js";
4
+ import { Button } from "./button.js";
5
+ import * as React from "react";
6
+ import { Popover, Select as Select$1 } from "radix-ui";
7
+ import { CheckIcon, ChevronDownIcon, ChevronUpIcon, XIcon } from "lucide-react";
8
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
9
+ //#region src/components/ui/select.tsx
10
+ /**
11
+ * Select — single-value dropdown over a fixed, bounded option list.
12
+ *
13
+ * Built on the Radix Select primitive with MMDS token-based styling. Size
14
+ * variants (default/sm/xs) are layered on via a `data-size` attribute.
15
+ */
16
+ function Select({ ...props }) {
17
+ return /* @__PURE__ */ jsx(Select$1.Root, {
18
+ "data-slot": "select",
19
+ ...props
20
+ });
21
+ }
22
+ function SelectGroup({ className, ...props }) {
23
+ return /* @__PURE__ */ jsx(Select$1.Group, {
24
+ "data-slot": "select-group",
25
+ className: cn("scroll-my-1 p-1", className),
26
+ ...props
27
+ });
28
+ }
29
+ function SelectValue({ inlineLabel, children, ...props }) {
30
+ return /* @__PURE__ */ jsx(Select$1.Value, {
31
+ "data-slot": "select-value",
32
+ ...props,
33
+ children: children != null && inlineLabel ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("span", {
34
+ className: "text-muted-foreground",
35
+ children: [inlineLabel, ": "]
36
+ }), children] }) : children
37
+ });
38
+ }
39
+ function SelectTrigger({ className, size = "default", children, ...props }) {
40
+ return /* @__PURE__ */ jsxs(Select$1.Trigger, {
41
+ "data-slot": "select-trigger",
42
+ "data-size": size,
43
+ className: cn("flex w-fit items-center justify-between gap-1.5 rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md,0.375rem),10px)] data-[size=xs]:h-6 data-[size=xs]:gap-1 data-[size=xs]:rounded-[min(var(--radius-md,0.375rem),8px)] data-[size=xs]:pr-1.5 data-[size=xs]:pl-2 data-[size=xs]:text-xs *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
44
+ ...props,
45
+ children: [children, /* @__PURE__ */ jsx(Select$1.Icon, {
46
+ asChild: true,
47
+ children: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "pointer-events-none size-4 text-muted-foreground" })
48
+ })]
49
+ });
50
+ }
51
+ function SelectContent({ className, children, position = "item-aligned", align = "center", ...props }) {
52
+ return /* @__PURE__ */ jsx(Select$1.Portal, {
53
+ container: getPortalContainer(),
54
+ children: /* @__PURE__ */ jsxs(Select$1.Content, {
55
+ "data-slot": "select-content",
56
+ "data-align-trigger": position === "item-aligned",
57
+ className: cn("relative z-50 max-h-(--radix-select-content-available-height) min-w-36 origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover text-popover-foreground shadow-popover ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95", position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1", className),
58
+ position,
59
+ align,
60
+ ...props,
61
+ children: [
62
+ /* @__PURE__ */ jsx(SelectScrollUpButton, {}),
63
+ /* @__PURE__ */ jsx(Select$1.Viewport, {
64
+ "data-position": position,
65
+ className: cn("data-[position=popper]:h-(--radix-select-trigger-height) data-[position=popper]:w-full data-[position=popper]:min-w-(--radix-select-trigger-width)", position === "popper" && ""),
66
+ children
67
+ }),
68
+ /* @__PURE__ */ jsx(SelectScrollDownButton, {})
69
+ ]
70
+ })
71
+ });
72
+ }
73
+ function SelectLabel({ className, ...props }) {
74
+ return /* @__PURE__ */ jsx(Select$1.Label, {
75
+ "data-slot": "select-label",
76
+ className: cn("px-1.5 py-1 text-xs text-muted-foreground", className),
77
+ ...props
78
+ });
79
+ }
80
+ function SelectItem({ className, children, ...props }) {
81
+ return /* @__PURE__ */ jsxs(Select$1.Item, {
82
+ "data-slot": "select-item",
83
+ className: cn("relative flex w-full cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2", className),
84
+ ...props,
85
+ children: [/* @__PURE__ */ jsx("span", {
86
+ className: "pointer-events-none absolute right-2 flex size-4 items-center justify-center",
87
+ children: /* @__PURE__ */ jsx(Select$1.ItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, { className: "pointer-events-none" }) })
88
+ }), /* @__PURE__ */ jsx(Select$1.ItemText, { children })]
89
+ });
90
+ }
91
+ function SelectSeparator({ className, ...props }) {
92
+ return /* @__PURE__ */ jsx(Select$1.Separator, {
93
+ "data-slot": "select-separator",
94
+ className: cn("pointer-events-none -mx-1 my-1 h-px bg-border", className),
95
+ ...props
96
+ });
97
+ }
98
+ function SelectScrollUpButton({ className, ...props }) {
99
+ return /* @__PURE__ */ jsx(Select$1.ScrollUpButton, {
100
+ "data-slot": "select-scroll-up-button",
101
+ className: cn("z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4", className),
102
+ ...props,
103
+ children: /* @__PURE__ */ jsx(ChevronUpIcon, {})
104
+ });
105
+ }
106
+ function SelectScrollDownButton({ className, ...props }) {
107
+ return /* @__PURE__ */ jsx(Select$1.ScrollDownButton, {
108
+ "data-slot": "select-scroll-down-button",
109
+ className: cn("z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4", className),
110
+ ...props,
111
+ children: /* @__PURE__ */ jsx(ChevronDownIcon, {})
112
+ });
113
+ }
114
+ var SelectMultipleContext = React.createContext(null);
115
+ function useSelectMultipleContext(component) {
116
+ const context = React.useContext(SelectMultipleContext);
117
+ if (!context) throw new Error(`${component} must be used within <SelectMultiple>.`);
118
+ return context;
119
+ }
120
+ function SelectMultiple({ value, onValueChange, size = "default", children, open: openProp, onOpenChange, closeOnSelect = false, ...props }) {
121
+ const labelsRef = React.useRef(/* @__PURE__ */ new Map());
122
+ const [labelsVersion, forceUpdate] = React.useReducer((n) => n + 1, 0);
123
+ const triggerRef = React.useRef(null);
124
+ const contentRef = React.useRef(null);
125
+ const [internalOpen, setInternalOpen] = React.useState(false);
126
+ const open = openProp ?? internalOpen;
127
+ const [triggerWidthOnOpen, setTriggerWidthOnOpen] = React.useState(void 0);
128
+ const setOpen = React.useCallback((next) => {
129
+ if (next) setTriggerWidthOnOpen(triggerRef.current?.getBoundingClientRect().width);
130
+ onOpenChange?.(next);
131
+ if (openProp === void 0) setInternalOpen(next);
132
+ }, [onOpenChange, openProp]);
133
+ React.useEffect(() => {
134
+ function handlePointerDown(event) {
135
+ const contentEl = contentRef.current;
136
+ if (!contentEl || contentEl.getAttribute("data-state") !== "open") return;
137
+ const target = event.target;
138
+ if (!(target instanceof Node)) return;
139
+ if (contentEl.contains(target)) return;
140
+ if (triggerRef.current?.contains(target)) return;
141
+ setOpen(false);
142
+ }
143
+ document.addEventListener("pointerdown", handlePointerDown);
144
+ return () => document.removeEventListener("pointerdown", handlePointerDown);
145
+ }, [setOpen]);
146
+ const registerLabel = React.useCallback((itemValue, label) => {
147
+ labelsRef.current.set(itemValue, label);
148
+ forceUpdate();
149
+ }, []);
150
+ const unregisterLabel = React.useCallback((itemValue) => {
151
+ labelsRef.current.delete(itemValue);
152
+ forceUpdate();
153
+ }, []);
154
+ const onItemSelect = React.useCallback((itemValue) => {
155
+ onValueChange(value.includes(itemValue) ? value.filter((v) => v !== itemValue) : [...value, itemValue]);
156
+ if (closeOnSelect) setOpen(false);
157
+ }, [
158
+ value,
159
+ onValueChange,
160
+ closeOnSelect,
161
+ setOpen
162
+ ]);
163
+ const clear = React.useCallback(() => onValueChange([]), [onValueChange]);
164
+ const context = React.useMemo(() => ({
165
+ value,
166
+ onItemSelect,
167
+ clear,
168
+ labels: labelsRef.current,
169
+ registerLabel,
170
+ unregisterLabel,
171
+ size,
172
+ triggerRef,
173
+ contentRef,
174
+ closeOnSelect,
175
+ triggerWidthOnOpen
176
+ }), [
177
+ value,
178
+ onItemSelect,
179
+ clear,
180
+ registerLabel,
181
+ unregisterLabel,
182
+ labelsVersion,
183
+ size,
184
+ closeOnSelect,
185
+ triggerWidthOnOpen
186
+ ]);
187
+ return /* @__PURE__ */ jsx(SelectMultipleContext.Provider, {
188
+ value: context,
189
+ children: /* @__PURE__ */ jsx(Popover.Root, {
190
+ "data-slot": "select-multiple",
191
+ open,
192
+ onOpenChange: setOpen,
193
+ ...props,
194
+ children
195
+ })
196
+ });
197
+ }
198
+ /** Shows only the first selected label — ellipsis-truncated at a character cap, applied whether or not anything else is selected, since the label alone can be too long to show whole in a `w-fit` trigger with no width of its own to truncate against — plus "+N" for the rest once there's more than one. No cap: the first label in full, still just the first. */
199
+ function buildMultiValueLabel(value, labels, maxChars) {
200
+ if (value.length === 0) return "";
201
+ const [first, ...rest] = value.map((v) => String(labels.get(v) ?? v));
202
+ const shown = maxChars !== void 0 && first.length > maxChars ? `${first.slice(0, maxChars)}…` : first;
203
+ return rest.length > 0 ? `${shown} +${rest.length}` : shown;
204
+ }
205
+ function SelectMultipleTrigger({ className, placeholder, disabled, maxLabelChars, inlineLabel, ...props }) {
206
+ const { value, labels, clear, size, triggerRef } = useSelectMultipleContext("SelectMultipleTrigger");
207
+ const hasValue = value.length > 0;
208
+ const valueLabel = buildMultiValueLabel(value, labels, maxLabelChars);
209
+ return /* @__PURE__ */ jsx(Popover.Trigger, {
210
+ disabled,
211
+ asChild: true,
212
+ ...props,
213
+ children: /* @__PURE__ */ jsxs("div", {
214
+ ref: triggerRef,
215
+ "data-slot": "select-multiple-trigger",
216
+ "data-size": size,
217
+ "data-placeholder": hasValue ? void 0 : "",
218
+ role: "button",
219
+ "aria-haspopup": "listbox",
220
+ tabIndex: disabled ? -1 : 0,
221
+ "aria-disabled": disabled || void 0,
222
+ onKeyDown: (event) => {
223
+ if (disabled) return;
224
+ if (event.target !== event.currentTarget) return;
225
+ if (event.key !== "Enter" && event.key !== " ") return;
226
+ event.preventDefault();
227
+ event.currentTarget.click();
228
+ },
229
+ className: cn("group flex w-fit items-center gap-1.5 rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-within:border-ring focus-within:ring-3 focus-within:ring-ring/50 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md,0.375rem),10px)] data-[size=xs]:h-6 data-[size=xs]:gap-1 data-[size=xs]:rounded-[min(var(--radius-md,0.375rem),8px)] data-[size=xs]:pr-1.5 data-[size=xs]:pl-2 data-[size=xs]:text-xs dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40", disabled ? "cursor-not-allowed opacity-50" : "cursor-pointer", className),
230
+ "aria-invalid": props["aria-invalid"],
231
+ children: [
232
+ /* @__PURE__ */ jsx("span", {
233
+ className: "min-w-0 flex-1 truncate text-left",
234
+ children: hasValue ? /* @__PURE__ */ jsxs(Fragment, { children: [inlineLabel && /* @__PURE__ */ jsxs("span", {
235
+ className: "text-muted-foreground",
236
+ children: [inlineLabel, ": "]
237
+ }), valueLabel] }) : placeholder
238
+ }),
239
+ hasValue && !disabled && /* @__PURE__ */ jsx(Button, {
240
+ type: "button",
241
+ variant: "ghost",
242
+ size: "xs",
243
+ iconOnly: true,
244
+ "aria-label": "Clear selection",
245
+ onClick: (event) => {
246
+ event.stopPropagation();
247
+ clear();
248
+ },
249
+ className: "shrink-0 text-muted-foreground",
250
+ children: /* @__PURE__ */ jsx(XIcon, { className: "pointer-events-none" })
251
+ }),
252
+ /* @__PURE__ */ jsx("span", {
253
+ role: "status",
254
+ className: "sr-only",
255
+ children: hasValue ? `${value.length} selected` : "None selected"
256
+ }),
257
+ /* @__PURE__ */ jsx(ChevronDownIcon, {
258
+ "aria-hidden": "true",
259
+ className: "size-4 shrink-0 text-muted-foreground transition-transform group-data-[state=open]:rotate-180"
260
+ })
261
+ ]
262
+ })
263
+ });
264
+ }
265
+ function SelectMultipleContent({ className, align = "start", sideOffset = 4, children, style, ...props }) {
266
+ const { size, contentRef, triggerWidthOnOpen } = useSelectMultipleContext("SelectMultipleContent");
267
+ const childArray = React.Children.toArray(children);
268
+ const isFooter = (child) => React.isValidElement(child) && child.type === SelectMultipleFooter;
269
+ const footer = childArray.filter(isFooter);
270
+ const items = childArray.filter((child) => !isFooter(child));
271
+ return /* @__PURE__ */ jsx(Popover.Portal, {
272
+ container: getPortalContainer(),
273
+ forceMount: true,
274
+ children: /* @__PURE__ */ jsxs(Popover.Content, {
275
+ ref: contentRef,
276
+ "data-slot": "select-multiple-content",
277
+ "data-size": size,
278
+ forceMount: true,
279
+ align,
280
+ sideOffset,
281
+ className: cn("z-50 max-h-(--radix-popover-content-available-height) max-w-[min(400px,var(--radix-popover-content-available-width))] min-w-[max(240px,var(--trigger-width-on-open,0px))] origin-(--radix-popover-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover p-1 text-popover-foreground shadow-popover ring-1 ring-foreground/10 outline-hidden duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[size=xs]:p-0.5 data-[state=closed]:hidden data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95", className),
282
+ style: {
283
+ ...triggerWidthOnOpen !== void 0 && { "--trigger-width-on-open": `${triggerWidthOnOpen}px` },
284
+ ...style
285
+ },
286
+ ...props,
287
+ children: [/* @__PURE__ */ jsx("div", {
288
+ role: "listbox",
289
+ "aria-multiselectable": "true",
290
+ className: "contents",
291
+ onKeyDown: (event) => {
292
+ if (![
293
+ "ArrowDown",
294
+ "ArrowUp",
295
+ "Home",
296
+ "End"
297
+ ].includes(event.key)) return;
298
+ const options = Array.from(event.currentTarget.querySelectorAll("[role=\"option\"]:not([data-disabled])"));
299
+ if (options.length === 0) return;
300
+ const currentIndex = options.indexOf(document.activeElement);
301
+ event.preventDefault();
302
+ options[event.key === "Home" ? 0 : event.key === "End" ? options.length - 1 : event.key === "ArrowDown" ? currentIndex < 0 ? 0 : (currentIndex + 1) % options.length : currentIndex < 0 ? options.length - 1 : (currentIndex - 1 + options.length) % options.length]?.focus();
303
+ },
304
+ children: items
305
+ }), footer]
306
+ })
307
+ });
308
+ }
309
+ /**
310
+ * Optional Cancel/Apply footer for `SelectMultipleContent` — pass a
311
+ * controlled `open` to `SelectMultiple` itself (see its own comment) and
312
+ * feed it a local pending draft instead of the real `value`/`onValueChange`
313
+ * while open, so picks only land for real once Apply commits that draft;
314
+ * Cancel just closes, discarding it. Renders as a sibling of the listbox,
315
+ * never inside it — see `SelectMultipleContent`'s own comment for why.
316
+ */
317
+ function SelectMultipleFooter({ className, ...props }) {
318
+ const { size } = useSelectMultipleContext("SelectMultipleFooter");
319
+ return /* @__PURE__ */ jsx("div", {
320
+ "data-slot": "select-multiple-footer",
321
+ className: cn("mt-1 flex items-center justify-end gap-1 border-t border-border pt-1.5", size === "xs" ? "-mx-0.5 w-[calc(100%+--spacing(1))] px-0.5" : "-mx-1 w-[calc(100%+--spacing(2))] px-1", className),
322
+ ...props
323
+ });
324
+ }
325
+ function SelectMultipleGroup({ className, ...props }) {
326
+ return /* @__PURE__ */ jsx("div", {
327
+ "data-slot": "select-multiple-group",
328
+ role: "group",
329
+ className: cn("scroll-my-1 p-1", className),
330
+ ...props
331
+ });
332
+ }
333
+ function SelectMultipleLabel({ className, ...props }) {
334
+ return /* @__PURE__ */ jsx("div", {
335
+ "data-slot": "select-multiple-label",
336
+ className: cn("px-1.5 py-1 text-xs text-muted-foreground", className),
337
+ ...props
338
+ });
339
+ }
340
+ function SelectMultipleItem({ className, children, value: itemValue, textValue, disabled, onClick, onKeyDown, ...props }) {
341
+ const { value, onItemSelect, registerLabel, unregisterLabel, size, closeOnSelect } = useSelectMultipleContext("SelectMultipleItem");
342
+ const checked = value.includes(itemValue);
343
+ React.useEffect(() => {
344
+ registerLabel(itemValue, textValue ?? (typeof children === "string" ? children : itemValue));
345
+ return () => unregisterLabel(itemValue);
346
+ }, [
347
+ itemValue,
348
+ textValue,
349
+ children,
350
+ registerLabel,
351
+ unregisterLabel
352
+ ]);
353
+ const select = () => {
354
+ if (disabled) return;
355
+ onItemSelect(itemValue);
356
+ };
357
+ return /* @__PURE__ */ jsxs("div", {
358
+ "data-slot": "select-multiple-item",
359
+ role: "option",
360
+ "aria-selected": checked,
361
+ "aria-disabled": disabled,
362
+ "data-disabled": disabled ? "" : void 0,
363
+ "data-size": size,
364
+ tabIndex: disabled ? -1 : 0,
365
+ className: cn("relative flex w-full cursor-default items-center gap-2 rounded-md py-1.5 pr-1.5 pl-1.5 text-sm outline-hidden select-none hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground data-[size=sm]:py-1 data-[size=xs]:gap-1.5 data-[size=xs]:py-0.5 data-[size=xs]:text-xs data-disabled:pointer-events-none data-disabled:opacity-50", className),
366
+ onClick: (e) => {
367
+ onClick?.(e);
368
+ select();
369
+ },
370
+ onKeyDown: (e) => {
371
+ onKeyDown?.(e);
372
+ if (e.key === "Enter" || e.key === " ") {
373
+ e.preventDefault();
374
+ select();
375
+ }
376
+ },
377
+ ...props,
378
+ children: [/* @__PURE__ */ jsx("span", {
379
+ "aria-hidden": "true",
380
+ "data-slot": "select-multiple-item-checkbox",
381
+ className: cn("relative flex size-4 shrink-0 items-center justify-center rounded-[4px] border border-input transition-colors", closeOnSelect && "rounded-full", checked && (closeOnSelect ? "border-primary" : "border-primary bg-primary text-primary-foreground"), disabled && "opacity-50"),
382
+ children: checked && (closeOnSelect ? /* @__PURE__ */ jsx("span", { className: "size-2 rounded-full bg-primary" }) : /* @__PURE__ */ jsx(CheckIcon, { className: "size-3.5" }))
383
+ }), /* @__PURE__ */ jsx("span", {
384
+ className: "inline-flex min-w-0 flex-1 items-center gap-1.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
385
+ children: typeof children === "string" ? /* @__PURE__ */ jsx("span", {
386
+ className: "min-w-0 flex-1 truncate",
387
+ children
388
+ }) : children
389
+ })]
390
+ });
391
+ }
392
+ function SelectMultipleSeparator({ className, ...props }) {
393
+ return /* @__PURE__ */ jsx("div", {
394
+ "data-slot": "select-multiple-separator",
395
+ className: cn("pointer-events-none -mx-1 my-1 h-px bg-border", className),
396
+ ...props
397
+ });
398
+ }
399
+ /**
400
+ * WHEN TO USE
401
+ * - Picking one value from a short, known, bounded list (settings, filters, form fields).
402
+ * - Options need grouping (SelectGroup + SelectLabel) or per-item disabling.
403
+ *
404
+ * NOT WHEN
405
+ * - The list is long enough to need type-to-filter — use Combobox instead.
406
+ * - Multiple values from a list that also needs search/filter — use Combobox's multi-select mode.
407
+ * - Native OS picker behavior (better on mobile, zero extra JS) is preferable — use NativeSelect instead.
408
+ *
409
+ * KEY RULES
410
+ * - SelectTrigger's `size` is "default" | "sm" | "xs" (default "default"); controls trigger
411
+ * height (h-8/h-7/h-6) and text size — same default/sm/xs vocabulary as Button/Item/
412
+ * Attachment/Tabs, not Select-specific naming.
413
+ * - SelectContent portals its content; `position="item-aligned"` (default) aligns to the trigger like a native select, `position="popper"` behaves like a standard popover.
414
+ * - Every SelectItem needs a `value`; the check indicator renders automatically for the selected item.
415
+ * - Put SelectSeparator between SelectGroups, not inside one.
416
+ * - SelectValue with no `children` auto-fills from the selected Item's own text — that's the
417
+ * normal, no-`inlineLabel` usage below. For "Label: Value" (e.g. "Assignee: James"), give
418
+ * SelectValue both `inlineLabel` and the current value's display text as `children` yourself —
419
+ * the auto-fill only runs with zero children, so a label prefix can't attach to it in place.
420
+ * - An AI-filled value is a plain composition, not a dedicated prop, and the same shape as
421
+ * Input's and Textarea's: put `AILabel` in the label row as a sibling of FieldLabel — never
422
+ * beside or inside SelectTrigger, which is itself a `<button>` (a button inside a button is
423
+ * invalid HTML, and would also open the listbox on every click of the marker) — while the
424
+ * value still matches what AI picked. Pass AILabel `edited={value !== aiValue}` and an
425
+ * `onRevert` that restores it, so picking a different value turns the marker into a ghost undo
426
+ * button (AILabel's own override/undo morph, same as Input/Textarea/Checkbox/RadioGroup). See
427
+ * Forms/Select.
428
+ *
429
+ * USAGE
430
+ * <Select>
431
+ * <SelectTrigger className="w-56">
432
+ * <SelectValue placeholder="Select a spice" />
433
+ * </SelectTrigger>
434
+ * <SelectContent>
435
+ * <SelectItem value="turmeric">Turmeric</SelectItem>
436
+ * <SelectItem value="cardamom">Cardamom</SelectItem>
437
+ * </SelectContent>
438
+ * </Select>
439
+ *
440
+ * // Inline-labeled trigger — "Spice: Turmeric" once a value is picked, plain
441
+ * // placeholder ("Select a spice") while nothing is
442
+ * <Select value={value} onValueChange={setValue}>
443
+ * <SelectTrigger className="w-56">
444
+ * <SelectValue placeholder="Select a spice" inlineLabel="Spice">
445
+ * {value || undefined}
446
+ * </SelectValue>
447
+ * </SelectTrigger>
448
+ * <SelectContent>
449
+ * <SelectItem value="turmeric">Turmeric</SelectItem>
450
+ * <SelectItem value="cardamom">Cardamom</SelectItem>
451
+ * </SelectContent>
452
+ * </Select>
453
+ *
454
+ * // Grouped, with a disabled item
455
+ * <Select defaultValue="cumin">
456
+ * <SelectTrigger className="w-56"><SelectValue placeholder="Select a spice" /></SelectTrigger>
457
+ * <SelectContent>
458
+ * <SelectGroup>
459
+ * <SelectLabel>Whole</SelectLabel>
460
+ * <SelectItem value="cardamom">Cardamom pod</SelectItem>
461
+ * </SelectGroup>
462
+ * <SelectSeparator />
463
+ * <SelectGroup>
464
+ * <SelectLabel>Ground</SelectLabel>
465
+ * <SelectItem value="turmeric">Turmeric</SelectItem>
466
+ * <SelectItem value="saffron" disabled>Saffron (out of stock)</SelectItem>
467
+ * </SelectGroup>
468
+ * </SelectContent>
469
+ * </Select>
470
+ *
471
+ * ---
472
+ *
473
+ * SelectMultiple — checkbox-list multi-select, no search/filter (see the
474
+ * doc block above SelectMultiple's definition for why this is a separate
475
+ * component tree rather than a `multiple` prop on Select).
476
+ *
477
+ * WHEN TO USE (SelectMultiple)
478
+ * - Picking several values from a short, known, bounded list where a search box
479
+ * would be overkill — settings toggles, tag pickers, filter panels.
480
+ *
481
+ * NOT WHEN (SelectMultiple)
482
+ * - The list is long enough to need type-to-filter — use Combobox's `multiple` mode instead.
483
+ *
484
+ * KEY RULES (SelectMultiple)
485
+ * - `value`/`onValueChange` are required and always an array — there is no uncontrolled mode.
486
+ * - `size` ("default" | "sm" | "xs", default "default") is set ONCE on SelectMultiple itself,
487
+ * not on Trigger or Content — it flows to both via context (Content is portaled, so it's
488
+ * never a CSS descendant of Trigger; a `group-data-[size]` selector couldn't reach it, which
489
+ * is why this is context-driven instead of the group/data-attribute trick Select/Tabs use).
490
+ * Trigger height/text and Content/Item padding/text/gap all scale together from this one prop.
491
+ * - The trigger shows only the first selected item's label (auto-collected from mounted
492
+ * SelectMultipleItems; pass `textValue` on an item if its children aren't plain text — e.g.
493
+ * an item with a leading icon or a secondary description line) plus "+N" once more than one
494
+ * is selected — never every label listed by name. Falls back to `placeholder` when empty,
495
+ * plus a clear-all "x" once non-empty. Pass `maxLabelChars` on SelectMultipleTrigger to
496
+ * ellipsis-truncate that one label past a character cap — applies even with a single value
497
+ * selected, since one long label can blow out a `w-fit` trigger same as a long list would
498
+ * (e.g. a narrow toolbar filter trigger). Pass
499
+ * `inlineLabel` to prefix the non-empty value with "{inlineLabel}: " (e.g. "Assignee: James") —
500
+ * `placeholder` alone still covers the empty state, no prefix there.
501
+ * - Clicking a SelectMultipleItem toggles it and leaves the popover open — this is the whole
502
+ * point of the variant; it never auto-closes on select the way Select/Combobox do. Pass
503
+ * `closeOnSelect` on SelectMultiple to close after any pick instead — for a single-effective-
504
+ * choice usage (cap `value` at one entry yourself) that still wants this component's non-modal
505
+ * Popover behavior (label stays visible while open, rest of the page stays interactive/
506
+ * scrollable) instead of Select's modal one. Don't reach for this as a general Select
507
+ * replacement — Select's native form participation, typeahead, and modality are worth keeping
508
+ * for ordinary form fields; this is for the specific case where a filter/action control needs
509
+ * to coexist non-modally with other controls the user is actively using (see DataTable's
510
+ * `singleSelect` inline filter for a real example). Also swaps every SelectMultipleItem's
511
+ * decorative indicator from a checkbox square to a radio dot — a checkbox otherwise visually
512
+ * promises "pick as many as you want", which is exactly wrong once picking one closes it.
513
+ * - SelectMultipleGroup/SelectMultipleLabel/SelectMultipleSeparator mirror Select's grouping API.
514
+ * - SelectMultiple forwards Radix Popover.Root's own props (`open`/`onOpenChange`/`defaultOpen`
515
+ * etc.) — useful for the Apply/Cancel pattern below, where something other than a plain click
516
+ * needs to control when the popover closes.
517
+ * - SelectMultipleContent/Portal use `forceMount` and hide via `data-[state=closed]:hidden` (a plain
518
+ * `display:none`) instead of letting Radix unmount on close — items must stay mounted while
519
+ * closed so their labels are already registered for the trigger's very first render, before
520
+ * the popover has ever been opened. `hidden` (not `invisible`) matters here specifically:
521
+ * `visibility:hidden` on the inner Content still lets Radix's outer popper-position wrapper
522
+ * div keep its layout box, which then silently intercepts clicks meant for elements behind
523
+ * it; `display:none` collapses that wrapper to nothing.
524
+ *
525
+ * USAGE
526
+ * const [value, setValue] = React.useState<string[]>(["cardamom"])
527
+ * <SelectMultiple value={value} onValueChange={setValue}>
528
+ * <SelectMultipleTrigger className="w-56" placeholder="Select spices" />
529
+ * <SelectMultipleContent>
530
+ * <SelectMultipleItem value="turmeric">Turmeric</SelectMultipleItem>
531
+ * <SelectMultipleItem value="cardamom">Cardamom</SelectMultipleItem>
532
+ * <SelectMultipleItem value="chili">Chili</SelectMultipleItem>
533
+ * </SelectMultipleContent>
534
+ * </SelectMultiple>
535
+ *
536
+ * // Dense popover — one prop scales trigger height AND item padding/text together
537
+ * <SelectMultiple value={value} onValueChange={setValue} size="xs">
538
+ * <SelectMultipleTrigger className="w-48" placeholder="Select spices" />
539
+ * <SelectMultipleContent>...</SelectMultipleContent>
540
+ * </SelectMultiple>
541
+ *
542
+ * // With an icon or a secondary description line — SelectMultipleItem's children is any
543
+ * // ReactNode; pass `textValue` so the trigger's comma-list still shows plain text
544
+ * <SelectMultipleItem value="cardamom" textValue="Cardamom">
545
+ * <LeafIcon />
546
+ * <span className="flex flex-col">
547
+ * Cardamom
548
+ * <span className="text-xs text-muted-foreground">Whole pods</span>
549
+ * </span>
550
+ * </SelectMultipleItem>
551
+ *
552
+ * // With search — filter by hiding non-matches, NOT by unmounting them: an unmounted
553
+ * // SelectMultipleItem unregisters its label, so a selected-but-filtered-out item would
554
+ * // fall back to showing its raw value in the trigger instead of its real label.
555
+ * const [query, setQuery] = React.useState("")
556
+ * <SelectMultipleContent>
557
+ * <Input value={query} onChange={(e) => setQuery(e.target.value)} placeholder="Search..." className="mb-1" />
558
+ * {spices.map((spice) => (
559
+ * <SelectMultipleItem
560
+ * key={spice}
561
+ * value={spice}
562
+ * className={cn(!spice.toLowerCase().includes(query.toLowerCase()) && "hidden")}
563
+ * >
564
+ * {spice}
565
+ * </SelectMultipleItem>
566
+ * ))}
567
+ * </SelectMultipleContent>
568
+ *
569
+ * // "Add option" (creatable) — the consumer already owns the list of items being mapped
570
+ * // over, so a no-results affordance is just appending to that list, same as any
571
+ * // Combobox-style creatable pattern; SelectMultiple needs no API for this.
572
+ * {query && !spices.some((s) => s.toLowerCase() === query.toLowerCase()) && (
573
+ * <button onClick={() => { setSpices((prev) => [...prev, query]); setValue((prev) => [...prev, query]) }}>
574
+ * Add "{query}"
575
+ * </button>
576
+ * )}
577
+ *
578
+ * // With a footer (Cancel | Apply) — stage picks in a local draft, only commit on Apply;
579
+ * // Cancel just closes without touching the real value. Uses the forwarded `open` prop.
580
+ * const [open, setOpen] = React.useState(false)
581
+ * const [applied, setApplied] = React.useState<string[]>([])
582
+ * const [draft, setDraft] = React.useState<string[]>(applied)
583
+ * <SelectMultiple
584
+ * value={draft}
585
+ * onValueChange={setDraft}
586
+ * open={open}
587
+ * onOpenChange={(next) => { if (next) setDraft(applied); setOpen(next) }}
588
+ * >
589
+ * <SelectMultipleTrigger className="w-56" placeholder="Select spices" />
590
+ * <SelectMultipleContent>
591
+ * {spices.map((spice) => <SelectMultipleItem key={spice} value={spice}>{spice}</SelectMultipleItem>)}
592
+ * <SelectMultipleSeparator />
593
+ * <div className="flex justify-end gap-1 p-1">
594
+ * <Button size="sm" variant="ghost" onClick={() => { setDraft(applied); setOpen(false) }}>Cancel</Button>
595
+ * <Button size="sm" onClick={() => { setApplied(draft); setOpen(false) }}>Apply</Button>
596
+ * </div>
597
+ * </SelectMultipleContent>
598
+ * </SelectMultiple>
599
+ *
600
+ * // "Select all" — a plain composition using the same Checkbox, no dedicated API:
601
+ * <Checkbox
602
+ * checked={value.length === 0 ? false : value.length === allValues.length ? true : "indeterminate"}
603
+ * onCheckedChange={(c) => setValue(c ? allValues : [])}
604
+ * />
605
+ */
606
+ //#endregion
607
+ export { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectMultiple, SelectMultipleContent, SelectMultipleFooter, SelectMultipleGroup, SelectMultipleItem, SelectMultipleLabel, SelectMultipleSeparator, SelectMultipleTrigger, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue };
608
+
609
+ //# sourceMappingURL=select.js.map