@justanarthur/modo-ui 0.5.0 → 0.6.0-canary.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 (461) hide show
  1. package/DESIGN.md +608 -0
  2. package/README.md +61 -39
  3. package/blocks/sidebar-app/examples.mdx +33 -0
  4. package/blocks/sidebar-app/index.tsx +218 -0
  5. package/blocks/sidebar-app/inset-topbar.tsx +25 -0
  6. package/blocks/sidebar-app/menu-grid.ts +26 -0
  7. package/blocks/sidebar-app/nav-data.ts +36 -0
  8. package/blocks/sidebar-app/search-field.tsx +48 -0
  9. package/blocks/sidebar-app/user-footer.tsx +67 -0
  10. package/blocks/sidebar-app/workspace-header.tsx +129 -0
  11. package/components/AI/input-message/examples.mdx +124 -0
  12. package/components/AI/input-message/file-thumbnail.tsx +173 -0
  13. package/components/AI/input-message/index.tsx +1383 -0
  14. package/components/AI/thinking-indicator/examples.mdx +27 -0
  15. package/components/AI/thinking-indicator/index.tsx +210 -0
  16. package/components/accordion/examples.mdx +148 -0
  17. package/components/accordion/index.tsx +1034 -0
  18. package/components/avatar/examples.mdx +95 -0
  19. package/components/avatar/index.tsx +129 -0
  20. package/components/badge/change-demo.tsx +29 -0
  21. package/components/badge/examples.mdx +120 -0
  22. package/components/badge/index.tsx +225 -0
  23. package/components/badge/variants.ts +73 -0
  24. package/components/button/examples.mdx +164 -0
  25. package/components/button/index.tsx +416 -0
  26. package/components/button/loading-demo.tsx +25 -0
  27. package/components/button/variants.ts +166 -0
  28. package/components/card/examples.mdx +212 -0
  29. package/components/card/index.tsx +1037 -0
  30. package/components/copy/examples.mdx +87 -0
  31. package/components/copy/index.tsx +482 -0
  32. package/components/inputs/checkbox/examples.mdx +83 -0
  33. package/components/inputs/checkbox/index.tsx +611 -0
  34. package/components/inputs/checkbox/select-all-demo.tsx +48 -0
  35. package/components/inputs/color-picker/examples.mdx +72 -0
  36. package/components/inputs/color-picker/index.tsx +1955 -0
  37. package/components/inputs/color-picker/variants.ts +401 -0
  38. package/components/inputs/combobox/examples.mdx +273 -0
  39. package/components/inputs/combobox/index.tsx +1436 -0
  40. package/components/inputs/combobox/remote-demo.tsx +101 -0
  41. package/components/inputs/date-time/calendar/examples.mdx +34 -0
  42. package/components/inputs/date-time/calendar/index.tsx +351 -0
  43. package/components/inputs/date-time/calendar/use-month-window.ts +163 -0
  44. package/components/inputs/date-time/date-picker/examples.mdx +166 -0
  45. package/components/inputs/date-time/date-picker/index.tsx +385 -0
  46. package/components/inputs/date-time/date-picker/masked-date-input.tsx +336 -0
  47. package/components/inputs/date-time/date-range-picker/examples.mdx +29 -0
  48. package/components/inputs/date-time/date-range-picker/index.tsx +217 -0
  49. package/components/inputs/date-time/duration-picker/examples.mdx +16 -0
  50. package/components/inputs/date-time/duration-picker/index.tsx +189 -0
  51. package/components/inputs/date-time/month-picker/examples.mdx +16 -0
  52. package/components/inputs/date-time/month-picker/index.tsx +190 -0
  53. package/components/inputs/date-time/picker-shell.tsx +395 -0
  54. package/components/inputs/date-time/time-columns.tsx +91 -0
  55. package/components/inputs/date-time/time-picker/examples.mdx +26 -0
  56. package/components/inputs/date-time/time-picker/index.tsx +166 -0
  57. package/components/inputs/field/examples.mdx +113 -0
  58. package/components/inputs/field/index.tsx +267 -0
  59. package/components/inputs/file-dropzone/examples.mdx +73 -0
  60. package/components/inputs/file-dropzone/file-row.tsx +201 -0
  61. package/components/inputs/file-dropzone/index.tsx +296 -0
  62. package/components/inputs/file-dropzone/upload-demo.tsx +67 -0
  63. package/components/inputs/file-dropzone/variants.ts +94 -0
  64. package/components/inputs/input/examples.mdx +135 -0
  65. package/components/inputs/input/index.tsx +494 -0
  66. package/components/inputs/input/password-demo.tsx +30 -0
  67. package/components/inputs/label/examples.mdx +67 -0
  68. package/components/inputs/label/index.tsx +85 -0
  69. package/components/inputs/number-input/examples.mdx +56 -0
  70. package/components/inputs/number-input/index.tsx +214 -0
  71. package/components/inputs/radio/examples.mdx +77 -0
  72. package/components/inputs/radio/index.tsx +636 -0
  73. package/components/inputs/search/examples.mdx +74 -0
  74. package/components/inputs/search/index.tsx +333 -0
  75. package/components/inputs/select/examples.mdx +218 -0
  76. package/components/inputs/select/index.tsx +862 -0
  77. package/components/inputs/select/variants.ts +32 -0
  78. package/components/inputs/slider/examples.mdx +127 -0
  79. package/components/inputs/slider/index.tsx +1725 -0
  80. package/components/inputs/switch/examples.mdx +94 -0
  81. package/components/inputs/switch/index.tsx +504 -0
  82. package/components/inputs/textarea/examples.mdx +88 -0
  83. package/components/inputs/textarea/index.tsx +161 -0
  84. package/components/navigation/navigation-menu/examples.mdx +109 -0
  85. package/components/navigation/navigation-menu/index.tsx +613 -0
  86. package/components/navigation/pagination/examples.mdx +64 -0
  87. package/components/navigation/pagination/index.tsx +395 -0
  88. package/components/navigation/sidebar/examples.mdx +319 -0
  89. package/components/navigation/sidebar/index.tsx +453 -0
  90. package/components/navigation/sidebar/sidebar-core.tsx +1408 -0
  91. package/components/navigation/sidebar/sidebar-menu.tsx +1495 -0
  92. package/components/navigation/sidebar/sidebar.css +74 -0
  93. package/components/navigation/sidebar/variants.ts +55 -0
  94. package/components/navigation/tabs/examples.mdx +89 -0
  95. package/components/navigation/tabs/index.tsx +494 -0
  96. package/components/navigation/tabs-subtle/examples.mdx +49 -0
  97. package/components/navigation/tabs-subtle/index.tsx +512 -0
  98. package/components/overlays/alert-dialog/examples.mdx +123 -0
  99. package/components/overlays/alert-dialog/index.tsx +258 -0
  100. package/components/overlays/alert-dialog/pending-demo.tsx +36 -0
  101. package/components/overlays/command/examples.mdx +113 -0
  102. package/components/overlays/command/index.tsx +416 -0
  103. package/components/overlays/context-menu/examples.mdx +56 -0
  104. package/components/overlays/context-menu/index.tsx +279 -0
  105. package/components/overlays/dialog/examples.mdx +144 -0
  106. package/components/overlays/dialog/index.tsx +366 -0
  107. package/components/overlays/dropdown/dropdown-search.tsx +395 -0
  108. package/components/overlays/dropdown/examples.mdx +294 -0
  109. package/components/overlays/dropdown/index.tsx +1168 -0
  110. package/components/overlays/dropdown/menu-item.tsx +464 -0
  111. package/components/overlays/dropdown/menu-parts.tsx +660 -0
  112. package/components/overlays/popover/anchored-demo.tsx +59 -0
  113. package/components/overlays/popover/examples.mdx +180 -0
  114. package/components/overlays/popover/index.tsx +315 -0
  115. package/components/overlays/preview-card/examples.mdx +61 -0
  116. package/components/overlays/preview-card/index.tsx +204 -0
  117. package/components/overlays/sheet/examples.mdx +89 -0
  118. package/components/overlays/sheet/index.tsx +247 -0
  119. package/components/overlays/toast/examples.mdx +68 -0
  120. package/components/overlays/toast/global-demo.tsx +72 -0
  121. package/components/overlays/toast/index.tsx +474 -0
  122. package/components/overlays/toast/manager.ts +193 -0
  123. package/components/overlays/tooltip/examples.mdx +106 -0
  124. package/components/overlays/tooltip/index.tsx +519 -0
  125. package/components/progress/examples.mdx +59 -0
  126. package/components/progress/index.tsx +174 -0
  127. package/components/progress/progress.css +49 -0
  128. package/components/progress/step-demo.tsx +27 -0
  129. package/components/table/examples.mdx +184 -0
  130. package/components/table/index.tsx +510 -0
  131. package/components/table/sort-demo.tsx +61 -0
  132. package/dist/base.css +100 -0
  133. package/dist/blocks/sidebar-app/index.js +39 -26
  134. package/dist/components/AI/input-message/index.js +22 -16
  135. package/dist/components/AI/thinking-indicator/index.js +9 -6
  136. package/dist/components/accordion/index.js +16 -13
  137. package/dist/components/avatar/index.d.ts +46 -0
  138. package/dist/components/avatar/index.js +18 -0
  139. package/dist/components/badge/index.d.ts +18 -11
  140. package/dist/components/badge/index.js +11 -7
  141. package/dist/components/badge/variants.d.ts +33 -0
  142. package/dist/components/badge/variants.js +10 -0
  143. package/dist/components/button/index.d.ts +53 -17
  144. package/dist/components/button/index.js +10 -6
  145. package/dist/components/button/variants.d.ts +39 -0
  146. package/dist/components/button/variants.js +8 -0
  147. package/dist/components/card/index.d.ts +16 -3
  148. package/dist/components/card/index.js +16 -11
  149. package/dist/components/copy/index.js +13 -9
  150. package/dist/components/inputs/checkbox/index.d.ts +28 -9
  151. package/dist/components/inputs/checkbox/index.js +17 -13
  152. package/dist/components/inputs/color-picker/index.d.ts +13 -13
  153. package/dist/components/inputs/color-picker/index.js +25 -18
  154. package/dist/components/inputs/color-picker/variants.d.ts +61 -0
  155. package/dist/components/inputs/color-picker/variants.js +28 -0
  156. package/dist/components/inputs/combobox/index.d.ts +60 -17
  157. package/dist/components/inputs/combobox/index.js +26 -18
  158. package/dist/components/inputs/date-time/calendar/index.js +14 -11
  159. package/dist/components/inputs/date-time/date-picker/index.d.ts +53 -11
  160. package/dist/components/inputs/date-time/date-picker/index.js +33 -25
  161. package/dist/components/inputs/date-time/date-range-picker/index.d.ts +3 -3
  162. package/dist/components/inputs/date-time/date-range-picker/index.js +32 -24
  163. package/dist/components/inputs/date-time/duration-picker/index.d.ts +3 -3
  164. package/dist/components/inputs/date-time/duration-picker/index.js +32 -24
  165. package/dist/components/inputs/date-time/month-picker/index.d.ts +3 -3
  166. package/dist/components/inputs/date-time/month-picker/index.js +31 -23
  167. package/dist/components/inputs/date-time/time-picker/index.d.ts +3 -3
  168. package/dist/components/inputs/date-time/time-picker/index.js +32 -24
  169. package/dist/components/inputs/field/index.d.ts +116 -0
  170. package/dist/components/inputs/field/index.js +28 -0
  171. package/dist/components/inputs/file-dropzone/index.d.ts +165 -0
  172. package/dist/components/inputs/file-dropzone/index.js +32 -0
  173. package/dist/components/inputs/file-dropzone/variants.d.ts +35 -0
  174. package/dist/components/inputs/file-dropzone/variants.js +12 -0
  175. package/dist/components/inputs/input/index.d.ts +95 -13
  176. package/dist/components/inputs/input/index.js +17 -9
  177. package/dist/components/inputs/label/index.d.ts +32 -0
  178. package/dist/components/inputs/label/index.js +11 -0
  179. package/dist/components/inputs/number-input/index.d.ts +84 -0
  180. package/dist/components/inputs/number-input/index.js +20 -0
  181. package/dist/components/inputs/radio/index.d.ts +20 -5
  182. package/dist/components/inputs/radio/index.js +15 -12
  183. package/dist/components/inputs/search/index.js +25 -18
  184. package/dist/components/inputs/select/index.d.ts +41 -11
  185. package/dist/components/inputs/select/index.js +27 -14
  186. package/dist/components/inputs/select/variants.d.ts +5 -0
  187. package/dist/components/inputs/select/variants.js +6 -0
  188. package/dist/components/inputs/slider/index.js +7 -5
  189. package/dist/components/inputs/switch/index.d.ts +8 -2
  190. package/dist/components/inputs/switch/index.js +14 -12
  191. package/dist/components/inputs/textarea/index.d.ts +4 -0
  192. package/dist/components/inputs/textarea/index.js +8 -6
  193. package/dist/components/navigation/navigation-menu/index.d.ts +114 -0
  194. package/dist/components/navigation/navigation-menu/index.js +40 -0
  195. package/dist/components/navigation/pagination/index.d.ts +73 -0
  196. package/dist/components/navigation/pagination/index.js +39 -0
  197. package/dist/components/navigation/sidebar/index.d.ts +44 -21
  198. package/dist/components/navigation/sidebar/index.js +41 -31
  199. package/dist/components/navigation/sidebar/variants.d.ts +25 -0
  200. package/dist/components/navigation/sidebar/variants.js +28 -0
  201. package/dist/components/navigation/tabs/index.d.ts +8 -2
  202. package/dist/components/navigation/tabs/index.js +14 -10
  203. package/dist/components/navigation/tabs-subtle/index.js +12 -10
  204. package/dist/components/overlays/alert-dialog/index.d.ts +121 -15
  205. package/dist/components/overlays/alert-dialog/index.js +22 -13
  206. package/dist/components/overlays/command/index.js +24 -17
  207. package/dist/components/overlays/context-menu/index.d.ts +33 -17
  208. package/dist/components/overlays/context-menu/index.js +27 -18
  209. package/dist/components/overlays/dialog/index.js +17 -12
  210. package/dist/components/overlays/dropdown/index.d.ts +257 -31
  211. package/dist/components/overlays/dropdown/index.js +42 -17
  212. package/dist/components/overlays/popover/index.d.ts +31 -9
  213. package/dist/components/overlays/popover/index.js +12 -9
  214. package/dist/components/overlays/preview-card/index.js +11 -8
  215. package/dist/components/overlays/sheet/index.js +18 -13
  216. package/dist/components/overlays/toast/index.d.ts +123 -47
  217. package/dist/components/overlays/toast/index.js +18 -10
  218. package/dist/components/overlays/tooltip/index.d.ts +113 -21
  219. package/dist/components/overlays/tooltip/index.js +15 -6
  220. package/dist/components/progress/index.d.ts +56 -0
  221. package/dist/components/progress/index.js +15 -0
  222. package/dist/components/table/index.d.ts +63 -8
  223. package/dist/components/table/index.js +19 -9
  224. package/dist/index.d.ts +2201 -736
  225. package/dist/index.js +223 -82
  226. package/dist/lib/date-locale.d.ts +14 -0
  227. package/dist/lib/date-locale.js +16 -0
  228. package/dist/lib/field-classes.d.ts +144 -0
  229. package/dist/lib/field-classes.js +40 -0
  230. package/dist/lib/field-variants.d.ts +47 -0
  231. package/dist/lib/field-variants.js +26 -0
  232. package/dist/lib/fluid-hover-highlight.d.ts +112 -0
  233. package/dist/lib/fluid-hover-highlight.js +17 -0
  234. package/dist/lib/focus-ring.d.ts +18 -0
  235. package/dist/lib/focus-ring.js +10 -0
  236. package/dist/lib/goo-indicator.d.ts +46 -0
  237. package/dist/lib/goo-indicator.js +14 -0
  238. package/dist/lib/icon-context.d.ts +30 -0
  239. package/dist/lib/icon-context.js +12 -0
  240. package/dist/lib/inert.d.ts +9 -0
  241. package/dist/lib/inert.js +8 -0
  242. package/dist/lib/morph-layers.d.ts +93 -0
  243. package/dist/lib/morph-layers.js +13 -0
  244. package/dist/lib/morph-part.d.ts +21 -0
  245. package/dist/lib/morph-part.js +12 -0
  246. package/dist/lib/popup.d.ts +20 -0
  247. package/dist/lib/popup.js +12 -0
  248. package/dist/lib/reduced-motion.d.ts +9 -0
  249. package/dist/lib/reduced-motion.js +6 -0
  250. package/dist/lib/row-index.d.ts +10 -0
  251. package/dist/lib/row-index.js +8 -0
  252. package/dist/lib/row-order.d.ts +28 -0
  253. package/dist/lib/row-order.js +10 -0
  254. package/dist/lib/scroll-column.d.ts +27 -0
  255. package/dist/lib/scroll-column.js +18 -0
  256. package/dist/lib/shape-context.d.ts +30 -0
  257. package/dist/lib/shape-context.js +12 -0
  258. package/dist/lib/size-context.d.ts +94 -0
  259. package/dist/lib/size-context.js +20 -0
  260. package/dist/lib/size-scale.d.ts +79 -0
  261. package/dist/lib/size-scale.js +8 -0
  262. package/dist/lib/slot.d.ts +12 -0
  263. package/dist/lib/slot.js +6 -0
  264. package/dist/lib/springs.d.ts +44 -0
  265. package/dist/lib/springs.js +8 -0
  266. package/dist/lib/surface-classes.d.ts +19 -0
  267. package/dist/lib/surface-classes.js +10 -0
  268. package/dist/lib/surface-context.d.ts +9 -0
  269. package/dist/lib/surface-context.js +8 -0
  270. package/dist/lib/use-controllable-state.d.ts +2 -0
  271. package/dist/lib/use-controllable-state.js +6 -0
  272. package/dist/lib/use-fluid-hover.d.ts +138 -0
  273. package/dist/lib/use-fluid-hover.js +14 -0
  274. package/dist/lib/use-is-mobile.d.ts +2 -0
  275. package/dist/lib/use-is-mobile.js +6 -0
  276. package/dist/lib/use-keyboard-nav-gate.d.ts +20 -0
  277. package/dist/lib/use-keyboard-nav-gate.js +7 -0
  278. package/dist/lib/use-merge-split.d.ts +47 -0
  279. package/dist/lib/use-merge-split.js +15 -0
  280. package/dist/lib/use-morph.d.ts +101 -0
  281. package/dist/lib/use-morph.js +20 -0
  282. package/dist/lib/use-touch-primary.d.ts +2 -0
  283. package/dist/lib/use-touch-primary.js +6 -0
  284. package/dist/lib/utils.d.ts +3 -0
  285. package/dist/lib/utils.js +6 -0
  286. package/dist/preset.d.ts +17 -0
  287. package/dist/preset.js +22 -2
  288. package/dist/primitives/code/index.js +7 -5
  289. package/dist/primitives/craft/index.js +9 -6
  290. package/dist/primitives/fluid-hover/index.js +9 -8
  291. package/dist/primitives/morph/index.js +15 -10
  292. package/dist/primitives/motion/index.js +10 -8
  293. package/dist/primitives/scroll-area/index.js +4 -3
  294. package/dist/primitives/separator/index.d.ts +25 -0
  295. package/dist/primitives/separator/index.js +9 -0
  296. package/dist/primitives/sizes/index.js +6 -4
  297. package/dist/primitives/skeleton/index.d.ts +35 -0
  298. package/dist/primitives/skeleton/index.js +12 -0
  299. package/dist/primitives/surface/index.js +6 -4
  300. package/dist/shared/{components-3mkepka5.js → components-0jmqhx2k.js} +28 -25
  301. package/dist/shared/components-124epb7f.js +53 -0
  302. package/dist/shared/{components-gz8zf3ec.js → components-1k0wv53d.js} +15 -43
  303. package/dist/shared/components-26snnbs9.js +322 -0
  304. package/dist/shared/{components-2dxkv6zm.js → components-2c0qcfx4.js} +8 -7
  305. package/dist/shared/{components-473g814w.js → components-2mt9te6d.js} +243 -137
  306. package/dist/shared/{components-hawvy2qz.js → components-2z48g4fp.js} +9 -30
  307. package/dist/shared/components-34txk9rj.js +35 -0
  308. package/dist/shared/components-3h92d94m.js +23 -0
  309. package/dist/shared/{components-zfnmn5d4.js → components-3sp623ae.js} +36 -31
  310. package/dist/shared/{components-jwst3vtj.js → components-3wxkjgqn.js} +186 -76
  311. package/dist/shared/{components-s2bz1xpk.js → components-49bsynbw.js} +8 -5
  312. package/dist/shared/components-4bwsd46w.js +71 -0
  313. package/dist/shared/components-4n4f5m3e.js +297 -0
  314. package/dist/shared/{components-0q0sqfh4.js → components-4y816hwp.js} +27 -49
  315. package/dist/shared/components-52ngsgca.js +399 -0
  316. package/dist/shared/{components-y9y0g8er.js → components-52r5763g.js} +22 -19
  317. package/dist/shared/components-559tf7yb.js +28 -0
  318. package/dist/shared/components-5mkga9hj.js +440 -0
  319. package/dist/shared/{components-kwa6mrf9.js → components-5s0nfqvw.js} +14 -9
  320. package/dist/shared/{components-dk0gjr5a.js → components-60atskhp.js} +19 -18
  321. package/dist/shared/{components-rr7a6ja9.js → components-658b26nb.js} +21 -18
  322. package/dist/shared/{components-xxvdw7k1.js → components-65vwfjs6.js} +37 -34
  323. package/dist/shared/{components-frw34b65.js → components-6j2fh74k.js} +114 -123
  324. package/dist/shared/components-6zg1yft7.js +167 -0
  325. package/dist/shared/components-6zng858q.js +53 -0
  326. package/dist/shared/components-72w4ge68.js +64 -0
  327. package/dist/shared/{components-cv16mryv.js → components-78x40gee.js} +13 -7
  328. package/dist/shared/{components-b2wyq2cq.js → components-7d4r7hh1.js} +39 -57
  329. package/dist/shared/components-7ntvvegr.js +316 -0
  330. package/dist/shared/components-8nwsqjn8.js +34 -0
  331. package/dist/shared/{components-5xc2j8jz.js → components-8tt3xbb5.js} +19 -18
  332. package/dist/shared/{components-vc7vq5nz.js → components-9as3rf68.js} +6 -3
  333. package/dist/shared/components-9mys9jna.js +255 -0
  334. package/dist/shared/components-adkarj8n.js +35 -0
  335. package/dist/shared/{components-b3c5et5b.js → components-ae9fncz4.js} +32 -31
  336. package/dist/shared/{components-hqeq3w9q.js → components-awra5sff.js} +24 -16
  337. package/dist/shared/components-b1e239g3.js +28 -0
  338. package/dist/shared/{components-q5xj5c16.js → components-b1f2bjf1.js} +9 -8
  339. package/dist/shared/{components-qmmjx1qw.js → components-bn42vq6d.js} +71 -72
  340. package/dist/shared/components-c96g82th.js +1444 -0
  341. package/dist/shared/components-c9yr4ed1.js +44 -0
  342. package/dist/shared/components-d3shbwqq.js +95 -0
  343. package/dist/shared/{components-jjw69c4c.js → components-dcc02hs2.js} +7 -4
  344. package/dist/shared/{components-men63rwj.js → components-de99ykt7.js} +3 -2
  345. package/dist/shared/components-dhgk6mbt.js +16 -0
  346. package/dist/shared/components-drxrtnp2.js +25 -0
  347. package/dist/shared/{components-6p8tfcd6.js → components-ds9fqat9.js} +21 -18
  348. package/dist/shared/{components-mjthm1kf.js → components-egy4tyjt.js} +11 -8
  349. package/dist/shared/components-f0xfpkhh.js +82 -0
  350. package/dist/shared/components-f7h57m6t.js +59 -0
  351. package/dist/shared/{components-d6xtjht3.js → components-fjkpbg6n.js} +33 -30
  352. package/dist/shared/{components-gc5vtq2f.js → components-gh0qeey3.js} +63 -29
  353. package/dist/shared/{components-39jq9va1.js → components-gvbapfen.js} +29 -24
  354. package/dist/shared/{components-5vgpnxgy.js → components-gzesg7hy.js} +19 -16
  355. package/dist/shared/components-h6p86be3.js +19 -0
  356. package/dist/shared/components-h83az0bz.js +33 -0
  357. package/dist/shared/components-jjrj6ymn.js +104 -0
  358. package/dist/shared/{components-wvp1m52g.js → components-jp5v0m0f.js} +15 -14
  359. package/dist/shared/{components-zrkzcayz.js → components-jqpefjsn.js} +54 -6
  360. package/dist/shared/{components-1z6tdadk.js → components-k74j4hwh.js} +20 -17
  361. package/dist/shared/components-kswxnm3h.js +24 -0
  362. package/dist/shared/{components-jbbmdr74.js → components-mkkbbgb7.js} +36 -17
  363. package/dist/shared/{components-pbmqctfa.js → components-mpw667rb.js} +169 -65
  364. package/dist/shared/{components-s5ngg32c.js → components-paa08427.js} +121 -47
  365. package/dist/shared/{components-vfbhxf5r.js → components-pd42emw3.js} +6 -5
  366. package/dist/shared/{components-hw9yk32z.js → components-pmfszv7a.js} +35 -23
  367. package/dist/shared/{components-chacnk61.js → components-pw06rbxq.js} +19 -19
  368. package/dist/shared/components-q03cktx8.js +246 -0
  369. package/dist/shared/{components-kvr7f9hy.js → components-qdm3yh26.js} +19 -10
  370. package/dist/shared/{components-27nnvrwe.js → components-qs4rkqsj.js} +15 -14
  371. package/dist/shared/{components-s083f38z.js → components-r6gbmkew.js} +22 -21
  372. package/dist/shared/{components-ta7shw28.js → components-r8eqs7gz.js} +4 -4
  373. package/dist/shared/{components-sn1rxx1d.js → components-rm02h9nt.js} +12 -11
  374. package/dist/shared/{components-c6s6b43g.js → components-rrbpmfx4.js} +3 -2
  375. package/dist/shared/{components-n7mjr357.js → components-tz1fv35x.js} +3 -2
  376. package/dist/shared/components-tz4gaf1v.js +23 -0
  377. package/dist/shared/{components-zx6b6yby.js → components-vf45j12c.js} +4 -18
  378. package/dist/shared/{components-3ky44908.js → components-vfjc9jzz.js} +2 -3
  379. package/dist/shared/{components-39vmfq9s.js → components-vsa625vk.js} +21 -20
  380. package/dist/shared/components-wawnmkph.js +500 -0
  381. package/dist/shared/components-wktrrb4m.js +38 -0
  382. package/dist/shared/{components-8snj490h.js → components-wwd363me.js} +78 -32
  383. package/dist/shared/{components-5pnw8183.js → components-xcwvgcrd.js} +23 -22
  384. package/dist/shared/components-xdqmt6ed.js +20 -0
  385. package/dist/shared/{components-h2ajmhwn.js → components-y1w3a6wx.js} +107 -35
  386. package/dist/shared/{components-ar66gnt0.js → components-y6578b8h.js} +37 -34
  387. package/dist/shared/{components-59efxjd9.js → components-yhgq0qxx.js} +13 -12
  388. package/dist/shared/{components-jthe1pwb.js → components-yz84gpkq.js} +101 -404
  389. package/dist/shared/components-z3v0n0de.js +11 -0
  390. package/dist/shared/{components-7r3etddy.js → components-z9n19fyk.js} +19 -54
  391. package/dist/shared/components-zbvjzh1p.js +141 -0
  392. package/dist/styles.css +241 -16
  393. package/dist/tailwind.css +13 -0
  394. package/dist/tokens.css +34 -0
  395. package/index.ts +60 -0
  396. package/lib/date-locale.ts +50 -0
  397. package/lib/field-classes.ts +115 -0
  398. package/lib/field-variants.ts +117 -0
  399. package/lib/fluid-hover-highlight.tsx +139 -0
  400. package/lib/focus-ring.tsx +46 -0
  401. package/lib/goo-indicator.tsx +261 -0
  402. package/lib/icon-context.tsx +310 -0
  403. package/lib/inert.ts +22 -0
  404. package/lib/morph-layers.tsx +102 -0
  405. package/lib/morph-part.tsx +49 -0
  406. package/lib/popup.ts +52 -0
  407. package/lib/reduced-motion.ts +19 -0
  408. package/lib/row-index.tsx +29 -0
  409. package/lib/row-order.tsx +115 -0
  410. package/lib/scroll-column.tsx +244 -0
  411. package/lib/shape-context.tsx +124 -0
  412. package/lib/size-context.tsx +66 -0
  413. package/lib/size-scale.ts +115 -0
  414. package/lib/slot.ts +25 -0
  415. package/lib/springs.ts +62 -0
  416. package/lib/surface-classes.ts +58 -0
  417. package/lib/surface-context.tsx +21 -0
  418. package/lib/use-controllable-state.ts +44 -0
  419. package/lib/use-fluid-hover.ts +541 -0
  420. package/lib/use-is-mobile.ts +25 -0
  421. package/lib/use-keyboard-nav-gate.ts +45 -0
  422. package/lib/use-merge-split.tsx +209 -0
  423. package/lib/use-morph.ts +557 -0
  424. package/lib/use-touch-primary.tsx +43 -0
  425. package/lib/utils.ts +37 -0
  426. package/package.json +177 -4
  427. package/preset.ts +196 -0
  428. package/primitives/code/examples.mdx +27 -0
  429. package/primitives/code/index.tsx +80 -0
  430. package/primitives/craft/demos.tsx +173 -0
  431. package/primitives/craft/examples.mdx +138 -0
  432. package/primitives/craft/index.tsx +76 -0
  433. package/primitives/fluid-hover/examples.mdx +84 -0
  434. package/primitives/fluid-hover/index.tsx +316 -0
  435. package/primitives/morph/examples.mdx +135 -0
  436. package/primitives/morph/index.tsx +192 -0
  437. package/primitives/motion/examples.mdx +100 -0
  438. package/primitives/motion/index.tsx +160 -0
  439. package/primitives/scroll-area/examples.mdx +58 -0
  440. package/primitives/scroll-area/index.tsx +200 -0
  441. package/primitives/separator/examples.mdx +30 -0
  442. package/primitives/separator/index.tsx +53 -0
  443. package/primitives/sizes/examples.mdx +167 -0
  444. package/primitives/sizes/index.tsx +89 -0
  445. package/primitives/skeleton/examples.mdx +51 -0
  446. package/primitives/skeleton/index.tsx +72 -0
  447. package/primitives/skeleton/skeleton.css +15 -0
  448. package/primitives/surface/examples.mdx +173 -0
  449. package/primitives/surface/index.tsx +109 -0
  450. package/primitives/surface/surface.css +176 -0
  451. package/dist/shared/components-0sn7ypjw.js +0 -61
  452. package/dist/shared/components-1434p1mh.js +0 -123
  453. package/dist/shared/components-a86dytt0.js +0 -986
  454. package/dist/shared/components-gf5s6ap9.js +0 -42
  455. package/dist/shared/components-hyq23phv.js +0 -310
  456. package/dist/shared/components-ng72k97e.js +0 -128
  457. package/dist/shared/components-raknhppb.js +0 -64
  458. package/dist/shared/components-vynjtrk6.js +0 -19
  459. package/dist/shared/components-wy9jpqny.js +0 -146
  460. /package/dist/shared/{components-1v7rxytx.js → components-3ey0hzpb.js} +0 -0
  461. /package/dist/shared/{components-ezxhrmer.js → components-jcnjay5g.js} +0 -0
@@ -0,0 +1,1444 @@
1
+ "use client";
2
+ import {
3
+ spring2
4
+ } from "./components-3ey0hzpb.js";
5
+ import {
6
+ opensInPlace2,
7
+ inPlaceOffset2,
8
+ useMorphOrigin2,
9
+ useMorph2
10
+ } from "./components-awra5sff.js";
11
+ import {
12
+ cn2
13
+ } from "./components-jcnjay5g.js";
14
+ import {
15
+ FluidHoverHighlight2
16
+ } from "./components-qdm3yh26.js";
17
+ import {
18
+ shapeMap2
19
+ } from "./components-78x40gee.js";
20
+ import {
21
+ FocusRing2
22
+ } from "./components-8nwsqjn8.js";
23
+ import {
24
+ MorphSurface2
25
+ } from "./components-4y816hwp.js";
26
+ import {
27
+ popupScrollAreaClass2,
28
+ popupViewportClass2,
29
+ isDisabledRow2
30
+ } from "./components-h6p86be3.js";
31
+ import {
32
+ RowOrderContext2,
33
+ useRowOrder2,
34
+ useRowSlot2
35
+ } from "./components-4bwsd46w.js";
36
+ import {
37
+ useSize2
38
+ } from "./components-h83az0bz.js";
39
+ import {
40
+ SURFACE_BG2,
41
+ SURFACE_SHADOW2
42
+ } from "./components-vf45j12c.js";
43
+ import {
44
+ useSurface2,
45
+ SurfaceProvider2
46
+ } from "./components-dhgk6mbt.js";
47
+ import {
48
+ useControllableState2
49
+ } from "./components-tz1fv35x.js";
50
+ import {
51
+ useFluidHover2,
52
+ useRegisterFluidHoverItem2
53
+ } from "./components-yhgq0qxx.js";
54
+ import {
55
+ useSelectionRuns2,
56
+ useMergeSplitBlocks2,
57
+ SelectionBackgrounds2
58
+ } from "./components-8tt3xbb5.js";
59
+ import {
60
+ ScrollArea2
61
+ } from "./components-2z48g4fp.js";
62
+ import {
63
+ SizeProvider2
64
+ } from "./components-dcc02hs2.js";
65
+ import {
66
+ Elevated2
67
+ } from "./components-9as3rf68.js";
68
+ import {
69
+ useIcon2
70
+ } from "./components-jqpefjsn.js";
71
+ import {
72
+ useKeyboardNavGate2
73
+ } from "./components-tz4gaf1v.js";
74
+
75
+ // components/overlays/dropdown/index.tsx
76
+ import { Menu as Menu2 } from "@base-ui/react/menu";
77
+ import { AnimatePresence as AnimatePresence2, motion as motion2 } from "motion/react";
78
+ import {
79
+ Children,
80
+ cloneElement,
81
+ createContext as createContext4,
82
+ forwardRef as forwardRef4,
83
+ isValidElement,
84
+ useCallback as useCallback3,
85
+ useContext as useContext4,
86
+ useEffect as useEffect4,
87
+ useImperativeHandle as useImperativeHandle2,
88
+ useMemo as useMemo3,
89
+ useRef as useRef4,
90
+ useState as useState3
91
+ } from "react";
92
+
93
+ // components/overlays/dropdown/dropdown-search.tsx
94
+ import {
95
+ createContext,
96
+ forwardRef,
97
+ useCallback,
98
+ useContext,
99
+ useEffect,
100
+ useMemo,
101
+ useRef,
102
+ useState
103
+ } from "react";
104
+ import { jsx, jsxs } from "react/jsx-runtime";
105
+ var DropdownSearchHostContext = createContext(null);
106
+ var DropdownFilterContext = createContext(null);
107
+ var ROW_SELECTOR = [
108
+ '[role="menuitem"]:not([aria-disabled="true"])',
109
+ '[role="menuitemradio"]:not([aria-disabled="true"])',
110
+ '[role="menuitemcheckbox"]:not([aria-disabled="true"])'
111
+ ].join(", ");
112
+ function menuRows(from) {
113
+ const menu = from?.closest('[role="menu"]');
114
+ return menu ? Array.from(menu.querySelectorAll(ROW_SELECTOR)) : [];
115
+ }
116
+ function useDropdownSearchHost(open, { containerRef, setActiveIndex }) {
117
+ const handleRef = useRef(null);
118
+ const [searchMounted, setSearchMounted] = useState(false);
119
+ const register = useCallback((handle) => {
120
+ handleRef.current = handle;
121
+ setSearchMounted(true);
122
+ return () => {
123
+ if (handleRef.current === handle) {
124
+ handleRef.current = null;
125
+ setSearchMounted(false);
126
+ }
127
+ };
128
+ }, []);
129
+ const highlightFirst = useCallback(() => {
130
+ const first = containerRef.current?.querySelector(ROW_SELECTOR);
131
+ const index = first?.getAttribute("data-fluid-hover-index");
132
+ setActiveIndex(index != null ? Number(index) : null);
133
+ }, [containerRef, setActiveIndex]);
134
+ const isSearchField = useCallback((target) => target !== null && target === handleRef.current?.input, []);
135
+ const host = useMemo(() => ({ register, open, highlightFirst }), [register, open, highlightFirst]);
136
+ const onKeyDownCapture = useCallback((e) => {
137
+ const handle = handleRef.current;
138
+ if (!handle?.input)
139
+ return;
140
+ if (e.target === handle.input)
141
+ return;
142
+ if (e.metaKey || e.ctrlKey || e.altKey)
143
+ return;
144
+ if (e.key.length === 1 && e.key !== " ") {
145
+ e.preventDefault();
146
+ e.stopPropagation();
147
+ handle.input.focus();
148
+ handle.append(e.key);
149
+ } else if (e.key === "Backspace") {
150
+ e.preventDefault();
151
+ e.stopPropagation();
152
+ handle.input.focus();
153
+ handle.deleteBackward();
154
+ }
155
+ }, []);
156
+ const hasSearch = useCallback(() => handleRef.current !== null, []);
157
+ return {
158
+ host,
159
+ hasSearch,
160
+ searchMounted,
161
+ onKeyDownCapture,
162
+ isSearchField,
163
+ highlightFirst
164
+ };
165
+ }
166
+ var DropdownSearch2 = forwardRef(({
167
+ value,
168
+ onValueChange,
169
+ filter = false,
170
+ placeholder = "Search…",
171
+ clearOnClose = true,
172
+ autoFocus = true,
173
+ className,
174
+ onKeyDown,
175
+ ...props
176
+ }, ref) => {
177
+ const SearchIcon = useIcon2("search");
178
+ const sizeClasses = useSize2();
179
+ const compact = sizeClasses.variant === "compact";
180
+ const host = useContext(DropdownSearchHostContext);
181
+ const open = host?.open ?? true;
182
+ const panel = useContext(DropdownFilterContext);
183
+ const managed = filter ? panel : null;
184
+ const query = managed ? managed.query : value ?? "";
185
+ const setQuery = useCallback((next) => {
186
+ managed?.setQuery(next);
187
+ onValueChange?.(next);
188
+ }, [managed, onValueChange]);
189
+ const surface = useSurface2();
190
+ const inputRef = useRef(null);
191
+ const valueRef = useRef(query);
192
+ valueRef.current = query;
193
+ const onValueChangeRef = useRef(setQuery);
194
+ onValueChangeRef.current = setQuery;
195
+ const clearOnCloseRef = useRef(clearOnClose);
196
+ clearOnCloseRef.current = clearOnClose;
197
+ useEffect(() => {
198
+ if (!host)
199
+ return;
200
+ return host.register({
201
+ get input() {
202
+ return inputRef.current;
203
+ },
204
+ append: (text) => onValueChangeRef.current(valueRef.current + text),
205
+ deleteBackward: () => onValueChangeRef.current(valueRef.current.slice(0, -1))
206
+ });
207
+ }, [host]);
208
+ useEffect(() => {
209
+ if (!open)
210
+ return;
211
+ if (clearOnCloseRef.current && valueRef.current !== "") {
212
+ onValueChangeRef.current("");
213
+ }
214
+ if (!autoFocus)
215
+ return;
216
+ let inner;
217
+ const outer = requestAnimationFrame(() => {
218
+ inner = requestAnimationFrame(() => inputRef.current?.focus());
219
+ });
220
+ return () => {
221
+ cancelAnimationFrame(outer);
222
+ if (inner !== undefined)
223
+ cancelAnimationFrame(inner);
224
+ };
225
+ }, [open, autoFocus]);
226
+ useEffect(() => {
227
+ if (!host || document.activeElement !== inputRef.current)
228
+ return;
229
+ host.highlightFirst();
230
+ }, [host, query]);
231
+ useEffect(() => () => {
232
+ if (clearOnCloseRef.current && valueRef.current !== "") {
233
+ onValueChangeRef.current("");
234
+ }
235
+ }, []);
236
+ const handleKeyDown = (e) => {
237
+ onKeyDown?.(e);
238
+ if (e.defaultPrevented)
239
+ return;
240
+ if (e.key === "Escape" || e.key === "Tab")
241
+ return;
242
+ e.stopPropagation();
243
+ if (e.key === "ArrowDown" || e.key === "ArrowUp") {
244
+ const rows = menuRows(e.currentTarget);
245
+ if (rows.length === 0)
246
+ return;
247
+ e.preventDefault();
248
+ (e.key === "ArrowDown" ? rows[0] : rows[rows.length - 1])?.focus();
249
+ } else if (e.key === "Enter") {
250
+ e.preventDefault();
251
+ menuRows(e.currentTarget)[0]?.click();
252
+ }
253
+ };
254
+ return /* @__PURE__ */ jsxs("div", {
255
+ className: cn2("group/search sticky top-0 z-20 -mx-1 -mt-1 mb-0.5 flex shrink-0 items-center border-b border-border/60", SURFACE_BG2[surface], sizeClasses.control, sizeClasses.gap, compact ? "px-2.5" : "px-3", className),
256
+ children: [
257
+ /* @__PURE__ */ jsx(SearchIcon, {
258
+ size: sizeClasses.icon,
259
+ strokeWidth: 1.5,
260
+ className: "shrink-0 text-muted-foreground transition-[color,stroke-width] duration-fast group-focus-within/search:text-foreground group-focus-within/search:stroke-[2]"
261
+ }),
262
+ /* @__PURE__ */ jsx("input", {
263
+ ref: (node) => {
264
+ inputRef.current = node;
265
+ if (typeof ref === "function")
266
+ ref(node);
267
+ else if (ref)
268
+ ref.current = node;
269
+ },
270
+ type: "text",
271
+ role: "searchbox",
272
+ autoComplete: "off",
273
+ autoCorrect: "off",
274
+ spellCheck: false,
275
+ value: query,
276
+ onChange: (e) => setQuery(e.target.value),
277
+ onKeyDown: handleKeyDown,
278
+ placeholder,
279
+ className: cn2("min-w-0 flex-1 rounded-none bg-transparent text-foreground placeholder:text-muted-foreground outline-none font-[inherit]", sizeClasses.text, compact ? "leading-5" : "leading-6"),
280
+ ...props
281
+ })
282
+ ]
283
+ });
284
+ });
285
+ DropdownSearch2.displayName = "DropdownSearch";
286
+ var DropdownEmpty2 = forwardRef(({ className, ...props }, ref) => {
287
+ const sizeClasses = useSize2();
288
+ return /* @__PURE__ */ jsx("div", {
289
+ ref,
290
+ role: "status",
291
+ "aria-live": "polite",
292
+ className: cn2("px-2 py-6 text-center text-muted-foreground", sizeClasses.text, className),
293
+ ...props
294
+ });
295
+ });
296
+ DropdownEmpty2.displayName = "DropdownEmpty";
297
+
298
+ // components/overlays/dropdown/menu-item.tsx
299
+ import { AnimatePresence, motion } from "motion/react";
300
+ import {
301
+ createContext as createContext2,
302
+ forwardRef as forwardRef2,
303
+ useContext as useContext2,
304
+ useEffect as useEffect2,
305
+ useRef as useRef2
306
+ } from "react";
307
+ import { jsx as jsx2, jsxs as jsxs2, Fragment } from "react/jsx-runtime";
308
+ var shape = shapeMap2.rounded;
309
+ var DropdownContext = createContext2(null);
310
+ function useDropdown2() {
311
+ const ctx = useContext2(DropdownContext);
312
+ if (!ctx)
313
+ throw new Error("useDropdown must be used within a Dropdown");
314
+ return ctx;
315
+ }
316
+ function useDropdownMaybe2() {
317
+ return useContext2(DropdownContext);
318
+ }
319
+ var INSET_PX = { default: "pl-8 pr-2", compact: "pl-6 pr-1.5" };
320
+ var FREEFORM_SVG = {
321
+ default: "[&>svg]:size-4 [&>svg]:shrink-0",
322
+ compact: "[&>svg]:size-3.5 [&>svg]:shrink-0"
323
+ };
324
+ var DropdownShortcut2 = forwardRef2(({ className, ...props }, ref) => {
325
+ const compact = useSize2().variant === "compact";
326
+ return /* @__PURE__ */ jsx2("kbd", {
327
+ ref,
328
+ className: cn2("ml-auto shrink-0 pl-4 font-sans text-muted-foreground", compact ? "text-caption-compact" : "text-caption", className),
329
+ ...props
330
+ });
331
+ });
332
+ DropdownShortcut2.displayName = "DropdownShortcut";
333
+ var MenuItem2 = forwardRef2(({
334
+ icon: Icon,
335
+ label,
336
+ index: indexProp,
337
+ children,
338
+ checked,
339
+ onSelect,
340
+ disabled,
341
+ closeOnClick,
342
+ inset,
343
+ shortcut,
344
+ sourceIndex,
345
+ kind,
346
+ value,
347
+ pinned,
348
+ className,
349
+ onClick,
350
+ ...props
351
+ }, ref) => {
352
+ const internalRef = useRef2(null);
353
+ const hasMounted = useRef2(false);
354
+ const {
355
+ registerItem,
356
+ activeIndex,
357
+ checkedIndex,
358
+ multiple,
359
+ checkedIndices,
360
+ renderMenuItem,
361
+ selfManaged,
362
+ toggleIndex,
363
+ reportChecked,
364
+ pin
365
+ } = useDropdown2();
366
+ const { index, firstRow } = useRowSlot2(internalRef, indexProp);
367
+ const authored = indexProp !== undefined;
368
+ const panelChecked = multiple ? checkedIndices?.includes(indexProp ?? -1) ?? false : checkedIndex === indexProp;
369
+ const isChecked = checked ?? (selfManaged && authored ? panelChecked : undefined);
370
+ const isCheckbox = kind ? kind === "checkbox" : !!multiple && typeof isChecked === "boolean";
371
+ const isRadio = kind ? kind === "radio" : !isCheckbox && typeof isChecked === "boolean";
372
+ useRegisterFluidHoverItem2(registerItem, index, internalRef);
373
+ useEffect2(() => {
374
+ if (!kind || !isChecked || index === undefined || !reportChecked)
375
+ return;
376
+ reportChecked(index, true);
377
+ return () => reportChecked(index, false);
378
+ }, [kind, isChecked, index, reportChecked]);
379
+ useEffect2(() => {
380
+ if (!pinned || index === undefined || !pin)
381
+ return;
382
+ pin(index, true);
383
+ return () => pin(index, false);
384
+ }, [pinned, index, pin]);
385
+ useEffect2(() => {
386
+ hasMounted.current = true;
387
+ }, []);
388
+ const isActive = index !== undefined && activeIndex === index;
389
+ const skipAnimation = !hasMounted.current;
390
+ const sizeClasses = useSize2();
391
+ const text = label ?? (typeof children === "string" ? children : undefined);
392
+ const freeform = label === undefined && text === undefined;
393
+ const lit = isActive || isChecked;
394
+ const mergeRef = (node) => {
395
+ internalRef.current = node;
396
+ if (typeof ref === "function")
397
+ ref(node);
398
+ else if (ref)
399
+ ref.current = node;
400
+ };
401
+ const activate = () => {
402
+ const event = new Event("select", { cancelable: true });
403
+ onSelect?.(event);
404
+ if (selfManaged && authored && !kind)
405
+ toggleIndex?.(sourceIndex ?? indexProp);
406
+ return event.defaultPrevented;
407
+ };
408
+ const handleActivate = disabled ? undefined : (e) => {
409
+ onClick?.(e);
410
+ if (activate())
411
+ e.preventBaseUIHandler?.();
412
+ };
413
+ const itemClassName = cn2(`relative z-10 flex ${sizeClasses.control} shrink-0 items-center ${sizeClasses.gap} ${shape.item} ${inset ? INSET_PX[sizeClasses.variant] : sizeClasses.itemPx} cursor-pointer outline-none`, freeform && [
414
+ sizeClasses.text,
415
+ FREEFORM_SVG[sizeClasses.variant],
416
+ "min-w-0 transition-[color,font-variation-settings] duration-fast",
417
+ lit ? "text-foreground" : "text-muted-foreground",
418
+ isChecked ? "weight-semibold" : "weight-normal"
419
+ ], disabled && "opacity-50 pointer-events-none", className);
420
+ const content = /* @__PURE__ */ jsxs2(Fragment, {
421
+ children: [
422
+ Icon && /* @__PURE__ */ jsxs2("span", {
423
+ className: "inline-grid",
424
+ children: [
425
+ /* @__PURE__ */ jsx2("span", {
426
+ className: "col-start-1 row-start-1 invisible",
427
+ children: /* @__PURE__ */ jsx2(Icon, {
428
+ size: sizeClasses.icon,
429
+ strokeWidth: 2
430
+ })
431
+ }),
432
+ /* @__PURE__ */ jsx2(Icon, {
433
+ size: sizeClasses.icon,
434
+ strokeWidth: lit ? 2 : 1.5,
435
+ className: cn2("col-start-1 row-start-1 transition-[color,stroke-width] duration-fast", lit ? "text-foreground" : "text-muted-foreground")
436
+ })
437
+ ]
438
+ }),
439
+ text !== undefined && /* @__PURE__ */ jsxs2("span", {
440
+ className: cn2("inline-grid min-w-0 flex-1", sizeClasses.text),
441
+ children: [
442
+ /* @__PURE__ */ jsx2("span", {
443
+ className: "col-start-1 row-start-1 invisible truncate [text-box:trim-both_cap_alphabetic] weight-semibold",
444
+ "aria-hidden": "true",
445
+ children: text
446
+ }),
447
+ /* @__PURE__ */ jsx2("span", {
448
+ className: cn2("col-start-1 row-start-1 truncate transition-[color,font-variation-settings] duration-fast [text-box:trim-both_cap_alphabetic]", lit ? "text-foreground" : "text-muted-foreground", isChecked ? "weight-semibold" : "weight-normal"),
449
+ children: text
450
+ })
451
+ ]
452
+ }),
453
+ label !== undefined || freeform ? children : null,
454
+ shortcut != null && /* @__PURE__ */ jsx2(DropdownShortcut2, {
455
+ children: shortcut
456
+ }),
457
+ /* @__PURE__ */ jsx2(AnimatePresence, {
458
+ children: isChecked && /* @__PURE__ */ jsx2(motion.svg, {
459
+ width: sizeClasses.icon,
460
+ height: sizeClasses.icon,
461
+ viewBox: "0 0 24 24",
462
+ fill: "none",
463
+ stroke: "currentColor",
464
+ strokeWidth: 2,
465
+ strokeLinecap: "round",
466
+ strokeLinejoin: "round",
467
+ className: cn2("text-foreground shrink-0", freeform && shortcut == null && "ml-auto"),
468
+ initial: { opacity: 1 },
469
+ animate: { opacity: 1 },
470
+ exit: { opacity: 1 },
471
+ children: /* @__PURE__ */ jsx2(motion.path, {
472
+ d: "M4 12L9 17L20 6",
473
+ initial: { pathLength: skipAnimation ? 1 : 0 },
474
+ animate: {
475
+ pathLength: 1,
476
+ transition: { duration: spring2.fast.duration, ease: "easeOut" }
477
+ },
478
+ exit: {
479
+ pathLength: 0,
480
+ transition: { duration: 0.04, ease: "easeIn" }
481
+ }
482
+ })
483
+ }, "check")
484
+ })
485
+ ]
486
+ });
487
+ if (renderMenuItem) {
488
+ return renderMenuItem({
489
+ radio: isRadio,
490
+ checkbox: isCheckbox,
491
+ checked: isChecked,
492
+ value: kind === "radio" ? value : index,
493
+ disabled,
494
+ label: text,
495
+ closeOnClick: closeOnClick ?? (kind ? kind === "radio" : !multiple),
496
+ onClick: handleActivate,
497
+ element: /* @__PURE__ */ jsx2("div", {
498
+ ref: mergeRef,
499
+ "data-fluid-hover-index": index,
500
+ "aria-label": label,
501
+ className: itemClassName,
502
+ ...props
503
+ }),
504
+ children: content
505
+ });
506
+ }
507
+ const tabStop = authored ? checkedIndex ?? checkedIndices?.[0] ?? 0 : firstRow;
508
+ return /* @__PURE__ */ jsx2("div", {
509
+ ref: mergeRef,
510
+ "data-fluid-hover-index": index,
511
+ tabIndex: !disabled && index === tabStop ? 0 : -1,
512
+ role: isCheckbox ? "menuitemcheckbox" : isRadio ? "menuitemradio" : "menuitem",
513
+ "aria-checked": typeof isChecked === "boolean" ? isChecked : undefined,
514
+ "aria-disabled": disabled || undefined,
515
+ "aria-label": label,
516
+ onClick: handleActivate,
517
+ onKeyDown: (e) => {
518
+ if (disabled)
519
+ return;
520
+ if (e.key === " " || e.key === "Enter") {
521
+ e.preventDefault();
522
+ activate();
523
+ }
524
+ },
525
+ className: itemClassName,
526
+ ...props,
527
+ children: content
528
+ });
529
+ });
530
+ MenuItem2.displayName = "MenuItem";
531
+
532
+ // components/overlays/dropdown/menu-parts.tsx
533
+ import { Menu } from "@base-ui/react/menu";
534
+ import {
535
+ createContext as createContext3,
536
+ forwardRef as forwardRef3,
537
+ useCallback as useCallback2,
538
+ useContext as useContext3,
539
+ useEffect as useEffect3,
540
+ useImperativeHandle,
541
+ useMemo as useMemo2,
542
+ useRef as useRef3,
543
+ useState as useState2
544
+ } from "react";
545
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
546
+ var shape2 = shapeMap2.rounded;
547
+ var NO_INDICES = [];
548
+ function mergeRefs(...refs) {
549
+ return (node) => {
550
+ for (const ref of refs) {
551
+ if (typeof ref === "function")
552
+ ref(node);
553
+ else if (ref)
554
+ ref.current = node;
555
+ }
556
+ };
557
+ }
558
+ var ownEvent = (e) => e.currentTarget.contains(e.target);
559
+ function renderPopupItem({
560
+ radio,
561
+ checkbox,
562
+ checked,
563
+ value,
564
+ disabled,
565
+ label,
566
+ closeOnClick,
567
+ onClick,
568
+ element,
569
+ children
570
+ }) {
571
+ if (checkbox)
572
+ return /* @__PURE__ */ jsx3(Menu.CheckboxItem, {
573
+ checked: !!checked,
574
+ disabled,
575
+ label,
576
+ closeOnClick,
577
+ onClick,
578
+ render: element,
579
+ children
580
+ });
581
+ if (radio)
582
+ return /* @__PURE__ */ jsx3(Menu.RadioItem, {
583
+ value,
584
+ disabled,
585
+ label,
586
+ closeOnClick,
587
+ onClick,
588
+ render: element,
589
+ children
590
+ });
591
+ return /* @__PURE__ */ jsx3(Menu.Item, {
592
+ disabled,
593
+ label,
594
+ closeOnClick,
595
+ onClick,
596
+ render: element,
597
+ children
598
+ });
599
+ }
600
+ function useValueChecked() {
601
+ const [valueChecked, setValueChecked] = useState2(NO_INDICES);
602
+ const reportChecked = useCallback2((index, on) => setValueChecked((prev) => on === prev.includes(index) ? prev : on ? [...prev, index] : prev.filter((i) => i !== index)), []);
603
+ return { valueChecked, reportChecked };
604
+ }
605
+ function useMenuPanel(containerRef, open) {
606
+ const hover = useFluidHover2(containerRef, { isItemDisabled: isDisabledRow2 });
607
+ const { activeIndex, setActiveIndex, itemRects, isMeasured } = hover;
608
+ const rowOrder = useRowOrder2();
609
+ const [focusedIndex, setFocusedIndex] = useState2(null);
610
+ const { keyboardNavRef, trackKeyboardNav } = useKeyboardNavGate2(open);
611
+ const [pinned, setPinned] = useState2(null);
612
+ const pin = useCallback2((index, on) => setPinned((p) => on ? index : p === index ? null : p), []);
613
+ const { valueChecked, reportChecked } = useValueChecked();
614
+ useEffect3(() => {
615
+ if (open)
616
+ return;
617
+ setFocusedIndex(null);
618
+ setActiveIndex(null);
619
+ }, [open, setActiveIndex]);
620
+ const lit = activeIndex ?? pinned;
621
+ const shownHover = useMemo2(() => ({ ...hover, activeIndex: lit }), [hover, lit]);
622
+ const focusRect = isMeasured && focusedIndex !== null ? itemRects[focusedIndex] ?? null : null;
623
+ const focusRow = useCallback2((e) => {
624
+ const row = e.target.closest("[data-fluid-hover-index]");
625
+ if (!row)
626
+ return false;
627
+ const index = Number(row.getAttribute("data-fluid-hover-index"));
628
+ setActiveIndex(isDisabledRow2(row) ? null : index);
629
+ setFocusedIndex(keyboardNavRef.current && e.target.matches(":focus-visible") ? index : null);
630
+ return true;
631
+ }, [keyboardNavRef, setActiveIndex]);
632
+ return {
633
+ hover,
634
+ shownHover,
635
+ lit,
636
+ rowOrder,
637
+ focusRect,
638
+ setFocusedIndex,
639
+ focusRow,
640
+ trackKeyboardNav,
641
+ pin,
642
+ valueChecked,
643
+ reportChecked
644
+ };
645
+ }
646
+ var DropdownGroupContext = createContext3(false);
647
+ var DropdownGroup2 = forwardRef3(({ className, ...props }, ref) => {
648
+ const own = useRef3(null);
649
+ useRowSlot2(own, undefined, true);
650
+ return /* @__PURE__ */ jsx3(DropdownGroupContext.Provider, {
651
+ value: true,
652
+ children: /* @__PURE__ */ jsx3(Menu.Group, {
653
+ ref: mergeRefs(own, ref),
654
+ className: cn2("flex flex-col", className),
655
+ ...props
656
+ })
657
+ });
658
+ });
659
+ DropdownGroup2.displayName = "DropdownGroup";
660
+ var DropdownCheckboxItem2 = forwardRef3(({ checked, defaultChecked = false, onCheckedChange, onSelect, closeOnClick = false, ...props }, ref) => {
661
+ const [on, setOn] = useControllableState2(checked, defaultChecked, onCheckedChange);
662
+ return /* @__PURE__ */ jsx3(MenuItem2, {
663
+ ref,
664
+ kind: "checkbox",
665
+ checked: on,
666
+ closeOnClick,
667
+ onSelect: (event) => {
668
+ onSelect?.(event);
669
+ setOn((prev) => !prev);
670
+ },
671
+ ...props
672
+ });
673
+ });
674
+ DropdownCheckboxItem2.displayName = "DropdownCheckboxItem";
675
+ var RadioValueContext = createContext3(null);
676
+ var DropdownRadioGroup2 = forwardRef3(({ value, defaultValue, onValueChange, className, ...props }, ref) => {
677
+ const [current, setCurrent] = useControllableState2(value, defaultValue, (next) => {
678
+ if (next !== undefined)
679
+ onValueChange?.(next);
680
+ });
681
+ const own = useRef3(null);
682
+ useRowSlot2(own, undefined, true);
683
+ const ctx = useMemo2(() => ({ value: current, select: (next) => setCurrent(next) }), [current, setCurrent]);
684
+ return /* @__PURE__ */ jsx3(RadioValueContext.Provider, {
685
+ value: ctx,
686
+ children: /* @__PURE__ */ jsx3(DropdownGroupContext.Provider, {
687
+ value: false,
688
+ children: /* @__PURE__ */ jsx3(Menu.RadioGroup, {
689
+ ref: mergeRefs(own, ref),
690
+ value: current ?? null,
691
+ className: cn2("flex flex-col", className),
692
+ ...props
693
+ })
694
+ })
695
+ });
696
+ });
697
+ DropdownRadioGroup2.displayName = "DropdownRadioGroup";
698
+ var DropdownRadioItem2 = forwardRef3(({ value, onSelect, ...props }, ref) => {
699
+ const group = useContext3(RadioValueContext);
700
+ return /* @__PURE__ */ jsx3(MenuItem2, {
701
+ ref,
702
+ kind: "radio",
703
+ value,
704
+ checked: group?.value === value,
705
+ onSelect: (event) => {
706
+ onSelect?.(event);
707
+ group?.select(value);
708
+ },
709
+ ...props
710
+ });
711
+ });
712
+ DropdownRadioItem2.displayName = "DropdownRadioItem";
713
+ var SubContext = createContext3(null);
714
+ function useSubContext() {
715
+ const ctx = useContext3(SubContext);
716
+ if (!ctx)
717
+ throw new Error("Dropdown.SubTrigger and Dropdown.SubContent must be inside <Dropdown.Sub>");
718
+ return ctx;
719
+ }
720
+ function DropdownSub2({ children, open, defaultOpen = false, onOpenChange, disabled = false }) {
721
+ const [current, setCurrent] = useControllableState2(open, defaultOpen, onOpenChange);
722
+ const { origin, capture } = useMorphOrigin2();
723
+ const ctx = useMemo2(() => ({ open: current, origin }), [current, origin]);
724
+ return /* @__PURE__ */ jsx3(SubContext.Provider, {
725
+ value: ctx,
726
+ children: /* @__PURE__ */ jsx3(Menu.SubmenuRoot, {
727
+ open: current,
728
+ disabled,
729
+ onOpenChange: (next, details) => {
730
+ if (next)
731
+ capture(details);
732
+ setCurrent(next);
733
+ },
734
+ children
735
+ })
736
+ });
737
+ }
738
+ DropdownSub2.displayName = "DropdownSub";
739
+ var DropdownSubTrigger2 = forwardRef3(({ openOnHover, delay, closeDelay, ...props }, ref) => {
740
+ const { open, origin } = useSubContext();
741
+ const parent = useDropdown2();
742
+ const Chevron = useIcon2("chevron-right");
743
+ const size = useSize2();
744
+ const ctx = useMemo2(() => ({
745
+ ...parent,
746
+ renderMenuItem: ({ disabled, label, onClick, element, children }) => /* @__PURE__ */ jsxs3(Menu.SubmenuTrigger, {
747
+ disabled,
748
+ label,
749
+ onClick,
750
+ openOnHover,
751
+ delay,
752
+ closeDelay,
753
+ render: element,
754
+ children: [
755
+ children,
756
+ /* @__PURE__ */ jsx3(Chevron, {
757
+ size: size.icon,
758
+ strokeWidth: open ? 2 : 1.5,
759
+ className: cn2("ml-auto shrink-0 transition-[color,stroke-width] duration-fast", open ? "text-foreground" : "text-muted-foreground")
760
+ })
761
+ ]
762
+ })
763
+ }), [parent, openOnHover, delay, closeDelay, Chevron, size.icon, open]);
764
+ const setTrigger = useCallback2((node) => {
765
+ if (node)
766
+ origin.current = { ...origin.current, trigger: node };
767
+ }, [origin]);
768
+ return /* @__PURE__ */ jsx3(DropdownContext.Provider, {
769
+ value: ctx,
770
+ children: /* @__PURE__ */ jsx3(MenuItem2, {
771
+ ref: mergeRefs(setTrigger, ref),
772
+ pinned: open,
773
+ ...props
774
+ })
775
+ });
776
+ });
777
+ DropdownSubTrigger2.displayName = "DropdownSubTrigger";
778
+ var DropdownSubContent2 = forwardRef3(({
779
+ children,
780
+ className,
781
+ side = "inline-end",
782
+ align = "start",
783
+ sideOffset = 8,
784
+ alignOffset = -4,
785
+ from,
786
+ effect,
787
+ tier = "moderate",
788
+ keepMounted = false
789
+ }, ref) => {
790
+ const { open, origin } = useSubContext();
791
+ const morph = useMorph2(open, origin, { from, effect, tier });
792
+ useImperativeHandle(ref, () => morph.popup, [morph.popup]);
793
+ const level = Math.min(useSurface2() + 2, 8);
794
+ const containerRef = useRef3(null);
795
+ const panel = useMenuPanel(containerRef, open);
796
+ const { hover, focusRow, setFocusedIndex } = panel;
797
+ const { handlers, setActiveIndex, registerItem, itemRects, remeasure } = hover;
798
+ useEffect3(() => {
799
+ if (open)
800
+ remeasure();
801
+ }, [open, remeasure]);
802
+ const runs = useSelectionRuns2(panel.valueChecked);
803
+ const blocks = useMergeSplitBlocks2(runs, itemRects, shape2.bgRadius);
804
+ const ctx = useMemo2(() => ({
805
+ registerItem,
806
+ activeIndex: panel.lit,
807
+ inMenu: true,
808
+ renderMenuItem: renderPopupItem,
809
+ pin: panel.pin,
810
+ reportChecked: panel.reportChecked
811
+ }), [registerItem, panel.lit, panel.pin, panel.reportChecked]);
812
+ return /* @__PURE__ */ jsx3(Menu.Portal, {
813
+ keepMounted,
814
+ children: /* @__PURE__ */ jsx3(Menu.Positioner, {
815
+ side,
816
+ align,
817
+ sideOffset,
818
+ alignOffset,
819
+ className: "z-50 outline-none",
820
+ children: /* @__PURE__ */ jsx3(Menu.Popup, {
821
+ ref: morph.popupRef,
822
+ onKeyDownCapture: (e) => ownEvent(e) && panel.trackKeyboardNav(e),
823
+ onMouseEnter: () => {
824
+ handlers.onMouseEnter();
825
+ setFocusedIndex(null);
826
+ },
827
+ onMouseMove: (e) => ownEvent(e) && handlers.onMouseMove(e),
828
+ onMouseLeave: handlers.onMouseLeave,
829
+ onClick: (e) => ownEvent(e) && handlers.onClick(e),
830
+ onFocus: (e) => {
831
+ if (!ownEvent(e) || focusRow(e))
832
+ return;
833
+ if (e.target !== e.currentTarget)
834
+ setActiveIndex(null);
835
+ },
836
+ onBlur: (e) => {
837
+ if (!ownEvent(e) || e.currentTarget.contains(e.relatedTarget))
838
+ return;
839
+ setFocusedIndex(null);
840
+ setActiveIndex(null);
841
+ },
842
+ className: "relative select-none outline-none",
843
+ children: /* @__PURE__ */ jsx3(SurfaceProvider2, {
844
+ value: level,
845
+ children: /* @__PURE__ */ jsx3(MorphSurface2, {
846
+ morph,
847
+ bg: SURFACE_BG2[level],
848
+ shadow: SURFACE_SHADOW2[3],
849
+ radius: shape2.container,
850
+ className: cn2("flex w-56 max-w-[var(--available-width)] max-h-[min(480px,var(--available-height))] flex-col overflow-hidden", shape2.container, className),
851
+ children: /* @__PURE__ */ jsx3(ScrollArea2, {
852
+ className: popupScrollAreaClass2,
853
+ viewportClassName: cn2(popupViewportClass2, "scroll-fade"),
854
+ children: /* @__PURE__ */ jsxs3("div", {
855
+ ref: containerRef,
856
+ className: "relative flex flex-col p-1",
857
+ children: [
858
+ /* @__PURE__ */ jsx3(SelectionBackgrounds2, {
859
+ blocks
860
+ }),
861
+ /* @__PURE__ */ jsx3(FluidHoverHighlight2, {
862
+ hover: panel.shownHover,
863
+ hidden: !open,
864
+ className: shape2.bg
865
+ }),
866
+ /* @__PURE__ */ jsx3(FocusRing2, {
867
+ rect: open ? panel.focusRect : null,
868
+ shape: "rounded"
869
+ }),
870
+ /* @__PURE__ */ jsx3(RowOrderContext2.Provider, {
871
+ value: panel.rowOrder,
872
+ children: /* @__PURE__ */ jsx3(DropdownContext.Provider, {
873
+ value: ctx,
874
+ children
875
+ })
876
+ })
877
+ ]
878
+ })
879
+ })
880
+ })
881
+ })
882
+ })
883
+ })
884
+ });
885
+ });
886
+ DropdownSubContent2.displayName = "DropdownSubContent";
887
+
888
+ // components/overlays/dropdown/index.tsx
889
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
890
+ var shape3 = shapeMap2.rounded;
891
+ var NONE = -1;
892
+ var NO_INDICES2 = [];
893
+ var NO_RECTS = [];
894
+ function usePanelSelection({
895
+ checkedIndex,
896
+ defaultCheckedIndex,
897
+ onCheckedIndexChange,
898
+ checkedIndices,
899
+ defaultCheckedIndices,
900
+ onCheckedIndicesChange
901
+ }, sourceOf, filtering) {
902
+ const [single, setSingle] = useControllableState2(defaultCheckedIndex === undefined ? checkedIndex ?? NONE : undefined, defaultCheckedIndex ?? NONE, (index) => onCheckedIndexChange?.(index === NONE ? undefined : index));
903
+ const [many, setMany] = useControllableState2(defaultCheckedIndices === undefined ? checkedIndices ?? NO_INDICES2 : undefined, defaultCheckedIndices ?? NO_INDICES2, (indices) => onCheckedIndicesChange?.(indices));
904
+ const multiple = checkedIndices != null || defaultCheckedIndices != null;
905
+ const selfManaged = defaultCheckedIndex !== undefined || defaultCheckedIndices !== undefined;
906
+ const toggleIndex = useCallback3((source) => {
907
+ if (multiple) {
908
+ setMany((prev) => prev.includes(source) ? prev.filter((i) => i !== source) : [...prev, source].sort((a, b) => a - b));
909
+ return;
910
+ }
911
+ setSingle(source);
912
+ }, [multiple, setMany, setSingle]);
913
+ const renderedIndex = useMemo3(() => {
914
+ if (single === NONE)
915
+ return;
916
+ const i = filtering ? sourceOf.indexOf(single) : single;
917
+ return i === -1 ? undefined : i;
918
+ }, [single, filtering, sourceOf]);
919
+ const renderedIndices = useMemo3(() => {
920
+ if (!multiple)
921
+ return;
922
+ if (!filtering)
923
+ return many;
924
+ return many.map((s) => sourceOf.indexOf(s)).filter((i) => i !== -1);
925
+ }, [multiple, many, filtering, sourceOf]);
926
+ return {
927
+ checkedIndex: renderedIndex,
928
+ checkedIndices: renderedIndices,
929
+ multiple,
930
+ selfManaged,
931
+ toggleIndex
932
+ };
933
+ }
934
+ function usePanelRows(children) {
935
+ const [query, setQuery] = useState3("");
936
+ const filtering = useMemo3(() => Children.toArray(children).some((child) => isValidElement(child) && child.type === DropdownSearch2 && child.props.filter), [children]);
937
+ const filterCtx = useMemo3(() => ({ query, setQuery }), [query]);
938
+ const { content, sourceOf } = useMemo3(() => {
939
+ if (!filtering)
940
+ return { content: children, sourceOf: NO_INDICES2 };
941
+ const needle = query.trim().toLowerCase();
942
+ const rendered = [];
943
+ const empties = [];
944
+ const sources = [];
945
+ for (const child of Children.toArray(children)) {
946
+ if (!isValidElement(child)) {
947
+ rendered.push(child);
948
+ continue;
949
+ }
950
+ if (child.type === DropdownEmpty2) {
951
+ empties.push(child);
952
+ continue;
953
+ }
954
+ const rowProps = child.props;
955
+ if (typeof rowProps.label !== "string" || typeof rowProps.index !== "number") {
956
+ rendered.push(child);
957
+ continue;
958
+ }
959
+ if (needle && !rowProps.label.toLowerCase().includes(needle))
960
+ continue;
961
+ rendered.push(cloneElement(child, {
962
+ index: sources.length,
963
+ sourceIndex: rowProps.index
964
+ }));
965
+ sources.push(rowProps.index);
966
+ }
967
+ if (sources.length === 0)
968
+ rendered.push(...empties);
969
+ return { content: rendered, sourceOf: sources };
970
+ }, [children, filtering, query]);
971
+ return { content, sourceOf, filtering, filterCtx: filtering ? filterCtx : null };
972
+ }
973
+ var Dropdown2 = forwardRef4(({
974
+ children,
975
+ checkedIndex,
976
+ defaultCheckedIndex,
977
+ onCheckedIndexChange,
978
+ checkedIndices,
979
+ defaultCheckedIndices,
980
+ onCheckedIndicesChange,
981
+ size,
982
+ className,
983
+ ...props
984
+ }, ref) => {
985
+ const containerRef = useRef4(null);
986
+ const hover = useFluidHover2(containerRef, { isItemDisabled: isDisabledRow2 });
987
+ const { activeIndex, setActiveIndex, itemRects, handlers, registerItem } = hover;
988
+ const [focusedIndex, setFocusedIndex] = useState3(null);
989
+ const rowOrder = useRowOrder2();
990
+ const { valueChecked, reportChecked } = useValueChecked();
991
+ const rows = usePanelRows(children);
992
+ const selection = usePanelSelection({
993
+ checkedIndex,
994
+ defaultCheckedIndex,
995
+ onCheckedIndexChange,
996
+ checkedIndices,
997
+ defaultCheckedIndices,
998
+ onCheckedIndicesChange
999
+ }, rows.sourceOf, rows.filtering);
1000
+ const multiple = selection.multiple;
1001
+ const checkedRect = !multiple && selection.checkedIndex != null ? itemRects[selection.checkedIndex] : null;
1002
+ const focusRect = focusedIndex !== null ? itemRects[focusedIndex] : null;
1003
+ const runs = useSelectionRuns2(useMemo3(() => [...selection.checkedIndices ?? NO_INDICES2, ...valueChecked], [selection.checkedIndices, valueChecked]));
1004
+ const blocks = useMergeSplitBlocks2(runs, itemRects, shape3.bgRadius);
1005
+ const panelCtx = useMemo3(() => ({
1006
+ registerItem,
1007
+ activeIndex,
1008
+ checkedIndex: selection.checkedIndex,
1009
+ multiple,
1010
+ checkedIndices: selection.checkedIndices,
1011
+ selfManaged: selection.selfManaged,
1012
+ toggleIndex: selection.toggleIndex,
1013
+ reportChecked
1014
+ }), [
1015
+ registerItem,
1016
+ activeIndex,
1017
+ selection.checkedIndex,
1018
+ multiple,
1019
+ selection.checkedIndices,
1020
+ selection.selfManaged,
1021
+ selection.toggleIndex,
1022
+ reportChecked
1023
+ ]);
1024
+ const panel = /* @__PURE__ */ jsx4(RowOrderContext2.Provider, {
1025
+ value: rowOrder,
1026
+ children: /* @__PURE__ */ jsx4(DropdownContext.Provider, {
1027
+ value: panelCtx,
1028
+ children: /* @__PURE__ */ jsx4(DropdownFilterContext.Provider, {
1029
+ value: rows.filterCtx,
1030
+ children: /* @__PURE__ */ jsxs4(Elevated2, {
1031
+ offset: 2,
1032
+ shadowLevel: 3,
1033
+ ref: (node) => {
1034
+ containerRef.current = node;
1035
+ if (typeof ref === "function")
1036
+ ref(node);
1037
+ else if (ref)
1038
+ ref.current = node;
1039
+ },
1040
+ onMouseEnter: handlers.onMouseEnter,
1041
+ onMouseMove: handlers.onMouseMove,
1042
+ onMouseLeave: handlers.onMouseLeave,
1043
+ onClick: handlers.onClick,
1044
+ onFocus: (e) => {
1045
+ const indexAttr = e.target.closest("[data-fluid-hover-index]")?.getAttribute("data-fluid-hover-index");
1046
+ if (indexAttr != null) {
1047
+ const idx = Number(indexAttr);
1048
+ setActiveIndex(idx);
1049
+ setFocusedIndex(e.target.matches(":focus-visible") ? idx : null);
1050
+ }
1051
+ },
1052
+ onBlur: (e) => {
1053
+ if (containerRef.current?.contains(e.relatedTarget))
1054
+ return;
1055
+ setFocusedIndex(null);
1056
+ setActiveIndex(null);
1057
+ },
1058
+ onKeyDown: (e) => {
1059
+ const items = Array.from(containerRef.current?.querySelectorAll('[role="menuitem"], [role="menuitemradio"], [role="menuitemcheckbox"]') ?? []);
1060
+ const currentIdx = items.indexOf(e.target);
1061
+ if (currentIdx === -1)
1062
+ return;
1063
+ if (["ArrowDown", "ArrowUp", "ArrowRight", "ArrowLeft"].includes(e.key)) {
1064
+ e.preventDefault();
1065
+ const next = ["ArrowDown", "ArrowRight"].includes(e.key) ? (currentIdx + 1) % items.length : (currentIdx - 1 + items.length) % items.length;
1066
+ items[next]?.focus();
1067
+ } else if (e.key === "Home") {
1068
+ e.preventDefault();
1069
+ items[0]?.focus();
1070
+ } else if (e.key === "End") {
1071
+ e.preventDefault();
1072
+ items[items.length - 1]?.focus();
1073
+ }
1074
+ },
1075
+ role: "group",
1076
+ className: cn2(`relative flex flex-col w-72 max-w-full p-1 select-none`, className),
1077
+ ...props,
1078
+ children: [
1079
+ /* @__PURE__ */ jsx4(SelectionBackgrounds2, {
1080
+ blocks
1081
+ }),
1082
+ /* @__PURE__ */ jsx4(AnimatePresence2, {
1083
+ children: checkedRect && /* @__PURE__ */ jsx4(motion2.div, {
1084
+ className: `absolute ${shape3.bg} bg-active pointer-events-none`,
1085
+ initial: false,
1086
+ animate: {
1087
+ top: checkedRect.top,
1088
+ left: checkedRect.left,
1089
+ width: checkedRect.width,
1090
+ height: checkedRect.height,
1091
+ opacity: 1
1092
+ },
1093
+ exit: { opacity: 0, transition: spring2.moderate.exit },
1094
+ transition: {
1095
+ ...spring2.moderate,
1096
+ opacity: { duration: spring2.fast.duration }
1097
+ }
1098
+ })
1099
+ }),
1100
+ /* @__PURE__ */ jsx4(FluidHoverHighlight2, {
1101
+ hover,
1102
+ from: checkedRect,
1103
+ className: shape3.bg
1104
+ }),
1105
+ /* @__PURE__ */ jsx4(AnimatePresence2, {
1106
+ children: focusRect && /* @__PURE__ */ jsx4(motion2.div, {
1107
+ className: `absolute ${shape3.focusRing} pointer-events-none z-20 border border-focus-ring`,
1108
+ initial: false,
1109
+ animate: {
1110
+ left: focusRect.left - 2,
1111
+ top: focusRect.top - 2,
1112
+ width: focusRect.width + 4,
1113
+ height: focusRect.height + 4
1114
+ },
1115
+ exit: { opacity: 0, transition: spring2.fast.exit },
1116
+ transition: {
1117
+ ...spring2.fast,
1118
+ opacity: { duration: spring2.fast.duration }
1119
+ }
1120
+ })
1121
+ }),
1122
+ rows.content
1123
+ ]
1124
+ })
1125
+ })
1126
+ })
1127
+ });
1128
+ return size ? /* @__PURE__ */ jsx4(SizeProvider2, {
1129
+ size,
1130
+ children: panel
1131
+ }) : panel;
1132
+ });
1133
+ Dropdown2.displayName = "Dropdown";
1134
+ var DropdownMenuContext = createContext4(null);
1135
+ function useDropdownMenuContext() {
1136
+ const ctx = useContext4(DropdownMenuContext);
1137
+ if (!ctx)
1138
+ throw new Error("DropdownMenu compound components must be inside <DropdownMenu>");
1139
+ return ctx;
1140
+ }
1141
+ function DropdownMenu2({
1142
+ children,
1143
+ open: openProp,
1144
+ defaultOpen = false,
1145
+ onOpenChange,
1146
+ disabled = false,
1147
+ size
1148
+ }) {
1149
+ const [internalOpen, setInternalOpen] = useState3(defaultOpen);
1150
+ const open = openProp !== undefined ? openProp : internalOpen;
1151
+ const { origin, capture } = useMorphOrigin2();
1152
+ const handleOpenChange = useCallback3((next, details) => {
1153
+ if (next)
1154
+ capture(details);
1155
+ if (openProp === undefined)
1156
+ setInternalOpen(next);
1157
+ onOpenChange?.(next);
1158
+ }, [openProp, onOpenChange, capture]);
1159
+ const ctx = useMemo3(() => ({ open, origin }), [open, origin]);
1160
+ const root = /* @__PURE__ */ jsx4(DropdownMenuContext.Provider, {
1161
+ value: ctx,
1162
+ children: /* @__PURE__ */ jsx4(Menu2.Root, {
1163
+ open,
1164
+ onOpenChange: handleOpenChange,
1165
+ disabled,
1166
+ modal: false,
1167
+ children
1168
+ })
1169
+ });
1170
+ return size ? /* @__PURE__ */ jsx4(SizeProvider2, {
1171
+ size,
1172
+ children: root
1173
+ }) : root;
1174
+ }
1175
+ DropdownMenu2.displayName = "DropdownMenu";
1176
+ var DropdownTrigger2 = forwardRef4(({ asChild, render, children, ...props }, ref) => asChild && isValidElement(children) ? /* @__PURE__ */ jsx4(Menu2.Trigger, {
1177
+ ref,
1178
+ render: children,
1179
+ ...props
1180
+ }) : /* @__PURE__ */ jsx4(Menu2.Trigger, {
1181
+ ref,
1182
+ render,
1183
+ ...props,
1184
+ children
1185
+ }));
1186
+ DropdownTrigger2.displayName = "DropdownTrigger";
1187
+ var DropdownContent2 = forwardRef4(({
1188
+ className,
1189
+ children,
1190
+ checkedIndex,
1191
+ defaultCheckedIndex,
1192
+ onCheckedIndexChange,
1193
+ checkedIndices,
1194
+ defaultCheckedIndices,
1195
+ onCheckedIndicesChange,
1196
+ side = "bottom",
1197
+ align = "start",
1198
+ sideOffset = 6,
1199
+ from,
1200
+ effect,
1201
+ hideSource,
1202
+ tier = "moderate",
1203
+ keepMounted = false
1204
+ }, ref) => {
1205
+ const { open, origin } = useDropdownMenuContext();
1206
+ const morph = useMorph2(open, origin, { from, effect, hideSource, tier });
1207
+ useImperativeHandle2(ref, () => morph.popup, [morph.popup]);
1208
+ const level = Math.min(useSurface2() + 2, 8);
1209
+ const containerRef = useRef4(null);
1210
+ const panel = useMenuPanel(containerRef, open);
1211
+ const { hover, focusRow, setFocusedIndex } = panel;
1212
+ const { setActiveIndex, itemRects, handlers, registerItem, remeasure } = hover;
1213
+ const rows = usePanelRows(children);
1214
+ const selection = usePanelSelection({
1215
+ checkedIndex,
1216
+ defaultCheckedIndex,
1217
+ onCheckedIndexChange,
1218
+ checkedIndices,
1219
+ defaultCheckedIndices,
1220
+ onCheckedIndicesChange
1221
+ }, rows.sourceOf, rows.filtering);
1222
+ const {
1223
+ host: searchHost,
1224
+ hasSearch,
1225
+ searchMounted,
1226
+ onKeyDownCapture: redirectTypingToSearch,
1227
+ isSearchField,
1228
+ highlightFirst
1229
+ } = useDropdownSearchHost(open, { containerRef, setActiveIndex });
1230
+ useEffect4(() => {
1231
+ if (!open)
1232
+ return;
1233
+ let inner;
1234
+ const outer = requestAnimationFrame(() => {
1235
+ inner = requestAnimationFrame(() => {
1236
+ if (hasSearch())
1237
+ return;
1238
+ const container = containerRef.current;
1239
+ if (!container || container.contains(document.activeElement) && document.activeElement !== container)
1240
+ return;
1241
+ const first = container.querySelector('[role="menuitem"]:not([aria-disabled="true"]), [role="menuitemradio"]:not([aria-disabled="true"]), [role="menuitemcheckbox"]:not([aria-disabled="true"])');
1242
+ first?.focus();
1243
+ });
1244
+ });
1245
+ return () => {
1246
+ cancelAnimationFrame(outer);
1247
+ if (inner !== undefined)
1248
+ cancelAnimationFrame(inner);
1249
+ };
1250
+ }, [open, hasSearch]);
1251
+ useEffect4(() => {
1252
+ if (!open)
1253
+ return;
1254
+ remeasure();
1255
+ }, [open, remeasure]);
1256
+ const multiple = selection.multiple;
1257
+ const checkedRect = !multiple && selection.checkedIndex != null ? itemRects[selection.checkedIndex] : null;
1258
+ const runs = useSelectionRuns2(useMemo3(() => [...selection.checkedIndices ?? NO_INDICES2, ...panel.valueChecked], [selection.checkedIndices, panel.valueChecked]));
1259
+ const blocks = useMergeSplitBlocks2(runs, open ? itemRects : NO_RECTS, shape3.bgRadius);
1260
+ const contentCtx = useMemo3(() => ({
1261
+ registerItem,
1262
+ activeIndex: panel.lit,
1263
+ checkedIndex: selection.checkedIndex,
1264
+ multiple,
1265
+ checkedIndices: selection.checkedIndices,
1266
+ inMenu: true,
1267
+ renderMenuItem: renderPopupItem,
1268
+ selfManaged: selection.selfManaged,
1269
+ toggleIndex: selection.toggleIndex,
1270
+ pin: panel.pin,
1271
+ reportChecked: panel.reportChecked
1272
+ }), [
1273
+ registerItem,
1274
+ panel.lit,
1275
+ selection.checkedIndex,
1276
+ multiple,
1277
+ selection.checkedIndices,
1278
+ selection.selfManaged,
1279
+ selection.toggleIndex,
1280
+ panel.pin,
1281
+ panel.reportChecked
1282
+ ]);
1283
+ return /* @__PURE__ */ jsx4(Menu2.Portal, {
1284
+ keepMounted,
1285
+ children: /* @__PURE__ */ jsx4(Menu2.Positioner, {
1286
+ side,
1287
+ align,
1288
+ sideOffset: opensInPlace2({ effect, hideSource }) ? inPlaceOffset2 : sideOffset,
1289
+ className: "z-50 outline-none",
1290
+ children: /* @__PURE__ */ jsx4(DropdownContext.Provider, {
1291
+ value: contentCtx,
1292
+ children: /* @__PURE__ */ jsx4(DropdownFilterContext.Provider, {
1293
+ value: rows.filterCtx,
1294
+ children: /* @__PURE__ */ jsx4(DropdownSearchHostContext.Provider, {
1295
+ value: searchHost,
1296
+ children: /* @__PURE__ */ jsx4(Menu2.Popup, {
1297
+ ref: morph.popupRef,
1298
+ onKeyDownCapture: (e) => {
1299
+ if (!ownEvent(e))
1300
+ return;
1301
+ panel.trackKeyboardNav(e);
1302
+ redirectTypingToSearch(e);
1303
+ },
1304
+ onMouseEnter: () => {
1305
+ handlers.onMouseEnter();
1306
+ setFocusedIndex(null);
1307
+ },
1308
+ onMouseMove: (e) => ownEvent(e) && handlers.onMouseMove(e),
1309
+ onClick: (e) => ownEvent(e) && handlers.onClick(e),
1310
+ onMouseLeave: () => {
1311
+ handlers.onMouseLeave();
1312
+ if (isSearchField(document.activeElement))
1313
+ highlightFirst();
1314
+ },
1315
+ onFocus: (e) => {
1316
+ if (!ownEvent(e) || focusRow(e))
1317
+ return;
1318
+ if (isSearchField(e.target)) {
1319
+ highlightFirst();
1320
+ } else if (e.target !== e.currentTarget) {
1321
+ setActiveIndex(null);
1322
+ }
1323
+ },
1324
+ onBlur: (e) => {
1325
+ if (!ownEvent(e) || e.currentTarget.contains(e.relatedTarget))
1326
+ return;
1327
+ setFocusedIndex(null);
1328
+ setActiveIndex(null);
1329
+ },
1330
+ className: "relative select-none outline-none",
1331
+ children: /* @__PURE__ */ jsx4(SurfaceProvider2, {
1332
+ value: level,
1333
+ children: /* @__PURE__ */ jsx4(MorphSurface2, {
1334
+ morph,
1335
+ bg: SURFACE_BG2[level],
1336
+ shadow: SURFACE_SHADOW2[3],
1337
+ radius: shape3.container,
1338
+ className: cn2(`flex flex-col w-72 max-w-full min-w-[var(--anchor-width)] max-h-[min(480px,var(--available-height))] overflow-hidden ${shape3.container}`, className),
1339
+ children: /* @__PURE__ */ jsx4(ScrollArea2, {
1340
+ className: popupScrollAreaClass2,
1341
+ viewportClassName: cn2(popupViewportClass2, !searchMounted && "scroll-fade"),
1342
+ children: /* @__PURE__ */ jsxs4("div", {
1343
+ ref: containerRef,
1344
+ className: "relative flex flex-col p-1",
1345
+ children: [
1346
+ /* @__PURE__ */ jsx4(SelectionBackgrounds2, {
1347
+ blocks
1348
+ }),
1349
+ /* @__PURE__ */ jsx4(AnimatePresence2, {
1350
+ children: checkedRect && /* @__PURE__ */ jsx4(motion2.div, {
1351
+ className: `absolute ${shape3.bg} bg-active pointer-events-none`,
1352
+ initial: false,
1353
+ animate: {
1354
+ top: checkedRect.top,
1355
+ left: checkedRect.left,
1356
+ width: checkedRect.width,
1357
+ height: checkedRect.height,
1358
+ opacity: 1
1359
+ },
1360
+ exit: { opacity: 0, transition: spring2.moderate.exit },
1361
+ transition: {
1362
+ ...spring2.moderate,
1363
+ opacity: { duration: spring2.fast.duration }
1364
+ }
1365
+ })
1366
+ }),
1367
+ /* @__PURE__ */ jsx4(FluidHoverHighlight2, {
1368
+ hover: panel.shownHover,
1369
+ from: checkedRect,
1370
+ className: shape3.bg
1371
+ }),
1372
+ /* @__PURE__ */ jsx4(FocusRing2, {
1373
+ rect: open ? panel.focusRect : null,
1374
+ shape: "rounded"
1375
+ }),
1376
+ /* @__PURE__ */ jsx4(RowOrderContext2.Provider, {
1377
+ value: panel.rowOrder,
1378
+ children: /* @__PURE__ */ jsx4(Menu2.RadioGroup, {
1379
+ value: selection.checkedIndex ?? null,
1380
+ className: "contents",
1381
+ children: rows.content
1382
+ })
1383
+ })
1384
+ ]
1385
+ })
1386
+ })
1387
+ })
1388
+ })
1389
+ })
1390
+ })
1391
+ })
1392
+ })
1393
+ })
1394
+ });
1395
+ });
1396
+ DropdownContent2.displayName = "DropdownContent";
1397
+ var DropdownLabel2 = forwardRef4(({ className, inset, ...props }, ref) => {
1398
+ const size = useSize2();
1399
+ const own = useRef4(null);
1400
+ useRowSlot2(own, undefined, true);
1401
+ const classes = cn2("py-1.5 shrink-0 text-muted-foreground", inset ? INSET_PX[size.variant] : "px-2", size.variant === "compact" ? "text-caption-compact" : "text-caption", className);
1402
+ return useContext4(DropdownGroupContext) ? /* @__PURE__ */ jsx4(Menu2.GroupLabel, {
1403
+ ref: mergeRefs(own, ref),
1404
+ className: classes,
1405
+ ...props
1406
+ }) : /* @__PURE__ */ jsx4("div", {
1407
+ ref: mergeRefs(own, ref),
1408
+ className: classes,
1409
+ ...props
1410
+ });
1411
+ });
1412
+ DropdownLabel2.displayName = "DropdownLabel";
1413
+ var DropdownSeparator2 = forwardRef4(({ className, ...props }, ref) => {
1414
+ const own = useRef4(null);
1415
+ useRowSlot2(own, undefined, true);
1416
+ return /* @__PURE__ */ jsx4("div", {
1417
+ ref: mergeRefs(own, ref),
1418
+ role: "separator",
1419
+ className: cn2("my-1 -mx-1 h-px shrink-0 bg-border/60", className),
1420
+ ...props
1421
+ });
1422
+ });
1423
+ DropdownSeparator2.displayName = "DropdownSeparator";
1424
+ Object.assign(Dropdown2, {
1425
+ Menu: DropdownMenu2,
1426
+ Trigger: DropdownTrigger2,
1427
+ Content: DropdownContent2,
1428
+ Item: MenuItem2,
1429
+ Label: DropdownLabel2,
1430
+ Separator: DropdownSeparator2,
1431
+ Search: DropdownSearch2,
1432
+ Empty: DropdownEmpty2,
1433
+ Group: DropdownGroup2,
1434
+ Shortcut: DropdownShortcut2,
1435
+ CheckboxItem: DropdownCheckboxItem2,
1436
+ RadioGroup: DropdownRadioGroup2,
1437
+ RadioItem: DropdownRadioItem2,
1438
+ Sub: DropdownSub2,
1439
+ SubTrigger: DropdownSubTrigger2,
1440
+ SubContent: DropdownSubContent2
1441
+ });
1442
+ var dropdown_default = Dropdown2;
1443
+
1444
+ export { DropdownSearch2, DropdownEmpty2, DropdownContext, useDropdown2, useDropdownMaybe2, DropdownShortcut2, MenuItem2, DropdownGroup2, DropdownCheckboxItem2, DropdownRadioGroup2, DropdownRadioItem2, DropdownSub2, DropdownSubTrigger2, DropdownSubContent2, Dropdown2, DropdownMenu2, DropdownTrigger2, DropdownContent2, DropdownLabel2, DropdownSeparator2, dropdown_default };