@justanarthur/modo-ui 0.6.0-canary.8 → 0.6.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 (490) hide show
  1. package/README.md +66 -164
  2. package/dist/base.css +4 -141
  3. package/dist/blocks/sidebar-app/index.js +26 -40
  4. package/dist/components/AI/input-message/index.js +16 -23
  5. package/dist/components/AI/thinking-indicator/index.js +6 -9
  6. package/dist/components/accordion/index.d.ts +11 -39
  7. package/dist/components/accordion/index.js +13 -18
  8. package/dist/components/badge/index.d.ts +11 -18
  9. package/dist/components/badge/index.js +7 -12
  10. package/dist/components/button/index.d.ts +17 -53
  11. package/dist/components/button/index.js +6 -11
  12. package/dist/components/card/index.d.ts +9 -32
  13. package/dist/components/card/index.js +11 -17
  14. package/dist/components/copy/index.d.ts +8 -41
  15. package/dist/components/copy/index.js +9 -15
  16. package/dist/components/inputs/checkbox/index.d.ts +9 -28
  17. package/dist/components/inputs/checkbox/index.js +13 -18
  18. package/dist/components/inputs/color-picker/index.d.ts +14 -22
  19. package/dist/components/inputs/color-picker/index.js +18 -26
  20. package/dist/components/inputs/combobox/index.d.ts +20 -85
  21. package/dist/components/inputs/combobox/index.js +18 -27
  22. package/dist/components/inputs/date-time/calendar/index.d.ts +18 -24
  23. package/dist/components/inputs/date-time/calendar/index.js +11 -15
  24. package/dist/components/inputs/date-time/date-picker/index.d.ts +16 -105
  25. package/dist/components/inputs/date-time/date-picker/index.js +25 -35
  26. package/dist/components/inputs/date-time/date-range-picker/index.d.ts +12 -106
  27. package/dist/components/inputs/date-time/date-range-picker/index.js +24 -35
  28. package/dist/components/inputs/date-time/duration-picker/index.d.ts +13 -66
  29. package/dist/components/inputs/date-time/duration-picker/index.js +24 -33
  30. package/dist/components/inputs/date-time/month-picker/index.d.ts +10 -60
  31. package/dist/components/inputs/date-time/month-picker/index.js +23 -32
  32. package/dist/components/inputs/date-time/time-picker/index.d.ts +10 -58
  33. package/dist/components/inputs/date-time/time-picker/index.js +24 -33
  34. package/dist/components/inputs/input/index.d.ts +13 -95
  35. package/dist/components/inputs/input/index.js +9 -18
  36. package/dist/components/inputs/radio/index.d.ts +5 -20
  37. package/dist/components/inputs/radio/index.js +12 -16
  38. package/dist/components/inputs/search/index.d.ts +3 -3
  39. package/dist/components/inputs/search/index.js +18 -26
  40. package/dist/components/inputs/select/index.d.ts +23 -99
  41. package/dist/components/inputs/select/index.js +14 -29
  42. package/dist/components/inputs/slider/index.d.ts +0 -9
  43. package/dist/components/inputs/slider/index.js +5 -8
  44. package/dist/components/inputs/switch/index.d.ts +2 -8
  45. package/dist/components/inputs/switch/index.js +12 -15
  46. package/dist/components/inputs/textarea/index.d.ts +1 -20
  47. package/dist/components/inputs/textarea/index.js +6 -9
  48. package/dist/components/navigation/sidebar/index.d.ts +21 -44
  49. package/dist/components/navigation/sidebar/index.js +31 -42
  50. package/dist/components/navigation/tabs/index.d.ts +2 -8
  51. package/dist/components/navigation/tabs/index.js +10 -15
  52. package/dist/components/navigation/tabs-subtle/index.js +10 -13
  53. package/dist/components/overlays/alert-dialog/index.d.ts +16 -135
  54. package/dist/components/overlays/alert-dialog/index.js +13 -23
  55. package/dist/components/overlays/command/index.d.ts +20 -25
  56. package/dist/components/overlays/command/index.js +17 -25
  57. package/dist/components/overlays/context-menu/index.d.ts +17 -39
  58. package/dist/components/overlays/context-menu/index.js +18 -29
  59. package/dist/components/overlays/dialog/index.d.ts +16 -42
  60. package/dist/components/overlays/dialog/index.js +12 -20
  61. package/dist/components/overlays/dropdown/index.d.ts +34 -304
  62. package/dist/components/overlays/dropdown/index.js +17 -44
  63. package/dist/components/overlays/popover/index.d.ts +12 -38
  64. package/dist/components/overlays/popover/index.js +9 -13
  65. package/dist/components/overlays/preview-card/index.js +8 -12
  66. package/dist/components/overlays/sheet/index.d.ts +8 -25
  67. package/dist/components/overlays/sheet/index.js +13 -19
  68. package/dist/components/overlays/toast/index.d.ts +50 -209
  69. package/dist/components/overlays/toast/index.js +10 -23
  70. package/dist/components/overlays/tooltip/index.d.ts +21 -123
  71. package/dist/components/overlays/tooltip/index.js +6 -16
  72. package/dist/components/table/index.d.ts +8 -63
  73. package/dist/components/table/index.js +9 -20
  74. package/dist/index.d.ts +1048 -2999
  75. package/dist/index.js +82 -231
  76. package/dist/preset.d.ts +0 -22
  77. package/dist/preset.js +2 -24
  78. package/dist/primitives/code/index.js +5 -8
  79. package/dist/primitives/craft/index.js +6 -10
  80. package/dist/primitives/fluid-hover/index.js +8 -10
  81. package/dist/primitives/morph/index.js +10 -16
  82. package/dist/primitives/motion/index.js +8 -11
  83. package/dist/primitives/scroll-area/index.js +3 -5
  84. package/dist/primitives/sizes/index.js +4 -6
  85. package/dist/primitives/surface/index.js +4 -6
  86. package/dist/shared/{components-4y816hwp.js → components-0q0sqfh4.js} +49 -27
  87. package/dist/shared/components-0sn7ypjw.js +61 -0
  88. package/dist/shared/{components-vc864c51.js → components-11da9ajg.js} +5 -8
  89. package/dist/shared/components-1434p1mh.js +123 -0
  90. package/dist/shared/{components-t2a3qmy9.js → components-1z6tdadk.js} +24 -40
  91. package/dist/shared/{components-qs4rkqsj.js → components-27nnvrwe.js} +14 -15
  92. package/dist/shared/{components-av5t26rc.js → components-2dxkv6zm.js} +7 -8
  93. package/dist/shared/{components-wqrvqq5p.js → components-2ecg8svx.js} +152 -234
  94. package/dist/shared/{components-3ydr2fqe.js → components-2ph6t61s.js} +34 -37
  95. package/dist/shared/{components-6gk118w3.js → components-39jq9va1.js} +24 -29
  96. package/dist/shared/components-3ky44908.js +9 -0
  97. package/dist/shared/{components-y1qvbawa.js → components-3mkepka5.js} +25 -28
  98. package/dist/shared/{components-xqszvkj4.js → components-4700p9kz.js} +22 -24
  99. package/dist/shared/{components-yhgq0qxx.js → components-59efxjd9.js} +12 -13
  100. package/dist/shared/{components-9j9abkct.js → components-5vgpnxgy.js} +27 -51
  101. package/dist/shared/{components-8tt3xbb5.js → components-5xc2j8jz.js} +18 -19
  102. package/dist/shared/{components-jymmaevv.js → components-6p8tfcd6.js} +29 -57
  103. package/dist/shared/{components-4nck8acq.js → components-7r3etddy.js} +54 -19
  104. package/dist/shared/{components-skfd7kff.js → components-8snj490h.js} +32 -78
  105. package/dist/shared/{components-ctqmge8t.js → components-b0eac83j.js} +30 -9
  106. package/dist/shared/{components-9sttq78t.js → components-b2wyq2cq.js} +59 -41
  107. package/dist/shared/{components-vkwq2k96.js → components-b3c5et5b.js} +38 -49
  108. package/dist/shared/{components-rrbpmfx4.js → components-c6s6b43g.js} +2 -3
  109. package/dist/shared/{components-pw06rbxq.js → components-chacnk61.js} +19 -19
  110. package/dist/shared/{components-71nbt03m.js → components-cv16mryv.js} +7 -26
  111. package/dist/shared/{components-eqze3y30.js → components-d6xtjht3.js} +30 -35
  112. package/dist/shared/{components-5y5shqfd.js → components-dk0gjr5a.js} +18 -19
  113. package/dist/shared/{components-khspp26b.js → components-fzrq6tr3.js} +34 -37
  114. package/dist/shared/{components-km7fhgbk.js → components-gc5vtq2f.js} +30 -66
  115. package/dist/shared/components-gf5s6ap9.js +42 -0
  116. package/dist/shared/{components-qqcmtrbv.js → components-gz8zf3ec.js} +55 -56
  117. package/dist/shared/{components-mattt5jp.js → components-h2ajmhwn.js} +35 -107
  118. package/dist/shared/{components-awra5sff.js → components-hqeq3w9q.js} +16 -24
  119. package/dist/shared/{components-5tzhqbcw.js → components-hw9yk32z.js} +24 -36
  120. package/dist/shared/components-hyq23phv.js +310 -0
  121. package/dist/shared/{components-8mt5bsv6.js → components-jbbmdr74.js} +22 -41
  122. package/dist/shared/{components-dcc02hs2.js → components-jjw69c4c.js} +4 -7
  123. package/dist/shared/{components-2syq4mwc.js → components-jthe1pwb.js} +420 -139
  124. package/dist/shared/{components-r7q1zm7r.js → components-jwst3vtj.js} +76 -224
  125. package/dist/shared/{components-qdm3yh26.js → components-kvr7f9hy.js} +10 -19
  126. package/dist/shared/{components-s8yqk2dc.js → components-kwa6mrf9.js} +11 -46
  127. package/dist/shared/{components-de99ykt7.js → components-men63rwj.js} +2 -3
  128. package/dist/shared/{components-6b0zb8z3.js → components-mjthm1kf.js} +9 -13
  129. package/dist/shared/{components-2c64r8c9.js → components-n42c79bz.js} +22 -23
  130. package/dist/shared/{components-tz1fv35x.js → components-n7mjr357.js} +2 -3
  131. package/dist/shared/components-ng72k97e.js +128 -0
  132. package/dist/shared/{components-dyae0y7h.js → components-pbmqctfa.js} +65 -169
  133. package/dist/shared/{components-px2zm7dc.js → components-q5xj5c16.js} +8 -9
  134. package/dist/shared/components-raknhppb.js +64 -0
  135. package/dist/shared/{components-8rb25gbe.js → components-rr7a6ja9.js} +27 -59
  136. package/dist/shared/{components-5012r6gr.js → components-s083f38z.js} +34 -164
  137. package/dist/shared/components-s5ngg32c.js +267 -0
  138. package/dist/shared/components-sn1rxx1d.js +143 -0
  139. package/dist/shared/{components-r8eqs7gz.js → components-ta7shw28.js} +4 -4
  140. package/dist/shared/{components-9as3rf68.js → components-vc7vq5nz.js} +3 -6
  141. package/dist/shared/{components-ft3zdc79.js → components-vfbhxf5r.js} +5 -6
  142. package/dist/shared/components-vynjtrk6.js +19 -0
  143. package/dist/shared/{components-w0xq6q9k.js → components-w1r67ag9.js} +149 -294
  144. package/dist/shared/{components-z0bqtvcp.js → components-w90endve.js} +72 -71
  145. package/dist/shared/{components-t5pk5nmc.js → components-wvp1m52g.js} +102 -149
  146. package/dist/shared/components-wy9jpqny.js +146 -0
  147. package/dist/shared/{components-5sxjeh6h.js → components-y9y0g8er.js} +28 -52
  148. package/dist/shared/components-ypp01w3p.js +986 -0
  149. package/dist/shared/{components-t50hrswb.js → components-zfnmn5d4.js} +36 -82
  150. package/dist/shared/{components-jqpefjsn.js → components-zrkzcayz.js} +6 -54
  151. package/dist/shared/{components-vf45j12c.js → components-zx6b6yby.js} +18 -4
  152. package/dist/styles.css +32 -320
  153. package/dist/tailwind.css +0 -16
  154. package/dist/tokens.css +0 -67
  155. package/package.json +4 -227
  156. package/DESIGN.md +0 -623
  157. package/blocks/sidebar-app/examples.mdx +0 -33
  158. package/blocks/sidebar-app/index.tsx +0 -218
  159. package/blocks/sidebar-app/inset-topbar.tsx +0 -25
  160. package/blocks/sidebar-app/menu-grid.ts +0 -26
  161. package/blocks/sidebar-app/nav-data.ts +0 -36
  162. package/blocks/sidebar-app/search-field.tsx +0 -48
  163. package/blocks/sidebar-app/user-footer.tsx +0 -67
  164. package/blocks/sidebar-app/workspace-header.tsx +0 -129
  165. package/components/AI/input-message/examples.mdx +0 -130
  166. package/components/AI/input-message/file-thumbnail.tsx +0 -173
  167. package/components/AI/input-message/index.tsx +0 -1385
  168. package/components/AI/thinking-indicator/examples.mdx +0 -27
  169. package/components/AI/thinking-indicator/index.tsx +0 -210
  170. package/components/accordion/examples.mdx +0 -233
  171. package/components/accordion/index.tsx +0 -1071
  172. package/components/avatar/examples.mdx +0 -95
  173. package/components/avatar/index.tsx +0 -129
  174. package/components/badge/change-demo.tsx +0 -29
  175. package/components/badge/examples.mdx +0 -124
  176. package/components/badge/index.tsx +0 -225
  177. package/components/badge/variants.ts +0 -73
  178. package/components/button/examples.mdx +0 -168
  179. package/components/button/index.tsx +0 -424
  180. package/components/button/loading-demo.tsx +0 -25
  181. package/components/button/variants.ts +0 -168
  182. package/components/card/examples.mdx +0 -251
  183. package/components/card/index.tsx +0 -1070
  184. package/components/copy/examples.mdx +0 -125
  185. package/components/copy/index.tsx +0 -662
  186. package/components/inputs/checkbox/examples.mdx +0 -87
  187. package/components/inputs/checkbox/index.tsx +0 -611
  188. package/components/inputs/checkbox/select-all-demo.tsx +0 -48
  189. package/components/inputs/color-picker/examples.mdx +0 -111
  190. package/components/inputs/color-picker/index.tsx +0 -1981
  191. package/components/inputs/color-picker/variants.ts +0 -401
  192. package/components/inputs/combobox/examples.mdx +0 -366
  193. package/components/inputs/combobox/index.tsx +0 -1527
  194. package/components/inputs/combobox/remote-demo.tsx +0 -105
  195. package/components/inputs/date-time/calendar/examples.mdx +0 -45
  196. package/components/inputs/date-time/calendar/index.tsx +0 -370
  197. package/components/inputs/date-time/calendar/use-month-window.ts +0 -173
  198. package/components/inputs/date-time/date-picker/examples.mdx +0 -243
  199. package/components/inputs/date-time/date-picker/index.tsx +0 -476
  200. package/components/inputs/date-time/date-picker/masked-date-input.tsx +0 -348
  201. package/components/inputs/date-time/date-range-picker/examples.mdx +0 -93
  202. package/components/inputs/date-time/date-range-picker/index.tsx +0 -525
  203. package/components/inputs/date-time/duration-picker/examples.mdx +0 -40
  204. package/components/inputs/date-time/duration-picker/index.tsx +0 -253
  205. package/components/inputs/date-time/month-picker/examples.mdx +0 -45
  206. package/components/inputs/date-time/month-picker/index.tsx +0 -254
  207. package/components/inputs/date-time/picker-shell.tsx +0 -581
  208. package/components/inputs/date-time/time-columns.tsx +0 -94
  209. package/components/inputs/date-time/time-picker/examples.mdx +0 -57
  210. package/components/inputs/date-time/time-picker/index.tsx +0 -227
  211. package/components/inputs/field/examples.mdx +0 -117
  212. package/components/inputs/field/index.tsx +0 -268
  213. package/components/inputs/file-dropzone/examples.mdx +0 -83
  214. package/components/inputs/file-dropzone/file-row.tsx +0 -201
  215. package/components/inputs/file-dropzone/index.tsx +0 -316
  216. package/components/inputs/file-dropzone/upload-demo.tsx +0 -67
  217. package/components/inputs/file-dropzone/variants.ts +0 -94
  218. package/components/inputs/input/examples.mdx +0 -166
  219. package/components/inputs/input/index.tsx +0 -494
  220. package/components/inputs/input/password-demo.tsx +0 -30
  221. package/components/inputs/label/examples.mdx +0 -67
  222. package/components/inputs/label/index.tsx +0 -85
  223. package/components/inputs/number-input/examples.mdx +0 -69
  224. package/components/inputs/number-input/index.tsx +0 -221
  225. package/components/inputs/radio/examples.mdx +0 -77
  226. package/components/inputs/radio/index.tsx +0 -636
  227. package/components/inputs/search/examples.mdx +0 -74
  228. package/components/inputs/search/index.tsx +0 -333
  229. package/components/inputs/select/examples.mdx +0 -296
  230. package/components/inputs/select/index.tsx +0 -1044
  231. package/components/inputs/select/variants.ts +0 -32
  232. package/components/inputs/slider/examples.mdx +0 -153
  233. package/components/inputs/slider/index.tsx +0 -1867
  234. package/components/inputs/switch/examples.mdx +0 -96
  235. package/components/inputs/switch/index.tsx +0 -504
  236. package/components/inputs/textarea/examples.mdx +0 -126
  237. package/components/inputs/textarea/index.tsx +0 -207
  238. package/components/navigation/navigation-menu/examples.mdx +0 -136
  239. package/components/navigation/navigation-menu/index.tsx +0 -704
  240. package/components/navigation/pagination/examples.mdx +0 -74
  241. package/components/navigation/pagination/index.tsx +0 -401
  242. package/components/navigation/sidebar/examples.mdx +0 -325
  243. package/components/navigation/sidebar/index.tsx +0 -453
  244. package/components/navigation/sidebar/sidebar-core.tsx +0 -1408
  245. package/components/navigation/sidebar/sidebar-menu.tsx +0 -1495
  246. package/components/navigation/sidebar/sidebar.css +0 -74
  247. package/components/navigation/sidebar/variants.ts +0 -55
  248. package/components/navigation/tabs/examples.mdx +0 -89
  249. package/components/navigation/tabs/index.tsx +0 -494
  250. package/components/navigation/tabs-subtle/examples.mdx +0 -49
  251. package/components/navigation/tabs-subtle/index.tsx +0 -512
  252. package/components/overlays/alert-dialog/examples.mdx +0 -123
  253. package/components/overlays/alert-dialog/index.tsx +0 -276
  254. package/components/overlays/alert-dialog/pending-demo.tsx +0 -36
  255. package/components/overlays/command/examples.mdx +0 -113
  256. package/components/overlays/command/index.tsx +0 -425
  257. package/components/overlays/context-menu/examples.mdx +0 -56
  258. package/components/overlays/context-menu/index.tsx +0 -279
  259. package/components/overlays/dialog/examples.mdx +0 -165
  260. package/components/overlays/dialog/index.tsx +0 -451
  261. package/components/overlays/dropdown/dropdown-search.tsx +0 -395
  262. package/components/overlays/dropdown/examples.mdx +0 -444
  263. package/components/overlays/dropdown/index.tsx +0 -1241
  264. package/components/overlays/dropdown/menu-item.tsx +0 -510
  265. package/components/overlays/dropdown/menu-parts.tsx +0 -725
  266. package/components/overlays/popover/anchored-demo.tsx +0 -59
  267. package/components/overlays/popover/examples.mdx +0 -203
  268. package/components/overlays/popover/index.tsx +0 -317
  269. package/components/overlays/preview-card/examples.mdx +0 -61
  270. package/components/overlays/preview-card/index.tsx +0 -204
  271. package/components/overlays/sheet/examples.mdx +0 -101
  272. package/components/overlays/sheet/index.tsx +0 -307
  273. package/components/overlays/toast/examples.mdx +0 -85
  274. package/components/overlays/toast/global-demo.tsx +0 -72
  275. package/components/overlays/toast/index.tsx +0 -544
  276. package/components/overlays/toast/manager.ts +0 -193
  277. package/components/overlays/tooltip/examples.mdx +0 -106
  278. package/components/overlays/tooltip/index.tsx +0 -539
  279. package/components/progress/examples.mdx +0 -59
  280. package/components/progress/index.tsx +0 -174
  281. package/components/progress/progress.css +0 -49
  282. package/components/progress/step-demo.tsx +0 -27
  283. package/components/table/examples.mdx +0 -188
  284. package/components/table/index.tsx +0 -535
  285. package/components/table/sort-demo.tsx +0 -61
  286. package/dist/components/avatar/index.d.ts +0 -46
  287. package/dist/components/avatar/index.js +0 -19
  288. package/dist/components/badge/variants.d.ts +0 -33
  289. package/dist/components/badge/variants.js +0 -10
  290. package/dist/components/button/variants.d.ts +0 -39
  291. package/dist/components/button/variants.js +0 -8
  292. package/dist/components/inputs/color-picker/variants.d.ts +0 -61
  293. package/dist/components/inputs/color-picker/variants.js +0 -28
  294. package/dist/components/inputs/field/index.d.ts +0 -116
  295. package/dist/components/inputs/field/index.js +0 -29
  296. package/dist/components/inputs/file-dropzone/index.d.ts +0 -167
  297. package/dist/components/inputs/file-dropzone/index.js +0 -33
  298. package/dist/components/inputs/file-dropzone/variants.d.ts +0 -35
  299. package/dist/components/inputs/file-dropzone/variants.js +0 -12
  300. package/dist/components/inputs/label/index.d.ts +0 -32
  301. package/dist/components/inputs/label/index.js +0 -11
  302. package/dist/components/inputs/number-input/index.d.ts +0 -87
  303. package/dist/components/inputs/number-input/index.js +0 -21
  304. package/dist/components/inputs/select/variants.d.ts +0 -5
  305. package/dist/components/inputs/select/variants.js +0 -6
  306. package/dist/components/navigation/navigation-menu/index.d.ts +0 -126
  307. package/dist/components/navigation/navigation-menu/index.js +0 -41
  308. package/dist/components/navigation/pagination/index.d.ts +0 -75
  309. package/dist/components/navigation/pagination/index.js +0 -41
  310. package/dist/components/navigation/sidebar/variants.d.ts +0 -25
  311. package/dist/components/navigation/sidebar/variants.js +0 -28
  312. package/dist/components/progress/index.d.ts +0 -56
  313. package/dist/components/progress/index.js +0 -15
  314. package/dist/docs/index.d.ts +0 -83
  315. package/dist/docs/index.js +0 -288
  316. package/dist/docs/vite.d.ts +0 -31
  317. package/dist/docs/vite.js +0 -45
  318. package/dist/lib/date-locale.d.ts +0 -26
  319. package/dist/lib/date-locale.js +0 -24
  320. package/dist/lib/field-classes.d.ts +0 -149
  321. package/dist/lib/field-classes.js +0 -41
  322. package/dist/lib/field-variants.d.ts +0 -47
  323. package/dist/lib/field-variants.js +0 -26
  324. package/dist/lib/fluid-hover-highlight.d.ts +0 -112
  325. package/dist/lib/fluid-hover-highlight.js +0 -17
  326. package/dist/lib/focus-ring.d.ts +0 -18
  327. package/dist/lib/focus-ring.js +0 -11
  328. package/dist/lib/goo-indicator.d.ts +0 -46
  329. package/dist/lib/goo-indicator.js +0 -14
  330. package/dist/lib/icon-context.d.ts +0 -30
  331. package/dist/lib/icon-context.js +0 -12
  332. package/dist/lib/inert.d.ts +0 -9
  333. package/dist/lib/inert.js +0 -8
  334. package/dist/lib/morph-layers.d.ts +0 -93
  335. package/dist/lib/morph-layers.js +0 -13
  336. package/dist/lib/morph-part.d.ts +0 -21
  337. package/dist/lib/morph-part.js +0 -12
  338. package/dist/lib/popup.d.ts +0 -20
  339. package/dist/lib/popup.js +0 -12
  340. package/dist/lib/reduced-motion.d.ts +0 -9
  341. package/dist/lib/reduced-motion.js +0 -6
  342. package/dist/lib/row-index.d.ts +0 -10
  343. package/dist/lib/row-index.js +0 -8
  344. package/dist/lib/row-order.d.ts +0 -28
  345. package/dist/lib/row-order.js +0 -10
  346. package/dist/lib/scroll-column.d.ts +0 -31
  347. package/dist/lib/scroll-column.js +0 -19
  348. package/dist/lib/shape-context.d.ts +0 -30
  349. package/dist/lib/shape-context.js +0 -13
  350. package/dist/lib/shape-radius.d.ts +0 -19
  351. package/dist/lib/shape-radius.js +0 -6
  352. package/dist/lib/size-context.d.ts +0 -94
  353. package/dist/lib/size-context.js +0 -20
  354. package/dist/lib/size-scale.d.ts +0 -79
  355. package/dist/lib/size-scale.js +0 -8
  356. package/dist/lib/slot.d.ts +0 -39
  357. package/dist/lib/slot.js +0 -14
  358. package/dist/lib/springs.d.ts +0 -44
  359. package/dist/lib/springs.js +0 -8
  360. package/dist/lib/surface-classes.d.ts +0 -19
  361. package/dist/lib/surface-classes.js +0 -10
  362. package/dist/lib/surface-context.d.ts +0 -9
  363. package/dist/lib/surface-context.js +0 -8
  364. package/dist/lib/use-controllable-state.d.ts +0 -2
  365. package/dist/lib/use-controllable-state.js +0 -6
  366. package/dist/lib/use-fluid-hover.d.ts +0 -138
  367. package/dist/lib/use-fluid-hover.js +0 -14
  368. package/dist/lib/use-is-mobile.d.ts +0 -2
  369. package/dist/lib/use-is-mobile.js +0 -6
  370. package/dist/lib/use-keyboard-nav-gate.d.ts +0 -20
  371. package/dist/lib/use-keyboard-nav-gate.js +0 -7
  372. package/dist/lib/use-merge-split.d.ts +0 -47
  373. package/dist/lib/use-merge-split.js +0 -15
  374. package/dist/lib/use-morph.d.ts +0 -101
  375. package/dist/lib/use-morph.js +0 -20
  376. package/dist/lib/use-touch-primary.d.ts +0 -2
  377. package/dist/lib/use-touch-primary.js +0 -6
  378. package/dist/lib/utils.d.ts +0 -3
  379. package/dist/lib/utils.js +0 -6
  380. package/dist/primitives/separator/index.d.ts +0 -25
  381. package/dist/primitives/separator/index.js +0 -9
  382. package/dist/primitives/skeleton/index.d.ts +0 -35
  383. package/dist/primitives/skeleton/index.js +0 -13
  384. package/dist/shared/components-124epb7f.js +0 -53
  385. package/dist/shared/components-1kab3j44.js +0 -337
  386. package/dist/shared/components-26snnbs9.js +0 -322
  387. package/dist/shared/components-34txk9rj.js +0 -35
  388. package/dist/shared/components-3h92d94m.js +0 -23
  389. package/dist/shared/components-4vfm04wq.js +0 -82
  390. package/dist/shared/components-54nq988h.js +0 -123
  391. package/dist/shared/components-7s7pykk5.js +0 -281
  392. package/dist/shared/components-7zkhz3r8.js +0 -399
  393. package/dist/shared/components-8v644a0s.js +0 -298
  394. package/dist/shared/components-a4evvq8h.js +0 -271
  395. package/dist/shared/components-adkarj8n.js +0 -35
  396. package/dist/shared/components-b1e239g3.js +0 -28
  397. package/dist/shared/components-b94t6qtj.js +0 -143
  398. package/dist/shared/components-c9yr4ed1.js +0 -44
  399. package/dist/shared/components-cwg1d0w6.js +0 -254
  400. package/dist/shared/components-d3shbwqq.js +0 -95
  401. package/dist/shared/components-dhgk6mbt.js +0 -16
  402. package/dist/shared/components-drxrtnp2.js +0 -25
  403. package/dist/shared/components-ej4r7wmj.js +0 -482
  404. package/dist/shared/components-f7h57m6t.js +0 -59
  405. package/dist/shared/components-fejdzvqc.js +0 -448
  406. package/dist/shared/components-gx4h5rbb.js +0 -40
  407. package/dist/shared/components-gyt7my41.js +0 -328
  408. package/dist/shared/components-h6p86be3.js +0 -19
  409. package/dist/shared/components-h83az0bz.js +0 -33
  410. package/dist/shared/components-hdzrqqpx.js +0 -55
  411. package/dist/shared/components-krtx3m5b.js +0 -84
  412. package/dist/shared/components-kswxnm3h.js +0 -24
  413. package/dist/shared/components-mpa2y6x8.js +0 -277
  414. package/dist/shared/components-mrbaxt8q.js +0 -62
  415. package/dist/shared/components-pt5ftm4p.js +0 -38
  416. package/dist/shared/components-rpw4md2b.js +0 -179
  417. package/dist/shared/components-rtadhd9j.js +0 -64
  418. package/dist/shared/components-tz4gaf1v.js +0 -23
  419. package/dist/shared/components-wbbckbw8.js +0 -34
  420. package/dist/shared/components-xdqmt6ed.js +0 -20
  421. package/dist/shared/components-xjkdvnbg.js +0 -107
  422. package/dist/shared/components-z3v0n0de.js +0 -11
  423. package/dist/shared/components-z6dfqtyt.js +0 -1545
  424. package/dist/tokens/colors.css +0 -230
  425. package/dist/tokens/motion.css +0 -40
  426. package/dist/tokens/radius.css +0 -10
  427. package/dist/tokens/spacing.css +0 -9
  428. package/dist/tokens/typography.css +0 -119
  429. package/docs/chrome.css +0 -120
  430. package/docs/chrome.tsx +0 -283
  431. package/docs/index.ts +0 -9
  432. package/docs/vite.ts +0 -85
  433. package/index.ts +0 -60
  434. package/lib/date-locale.ts +0 -195
  435. package/lib/field-classes.ts +0 -121
  436. package/lib/field-variants.ts +0 -117
  437. package/lib/fluid-hover-highlight.tsx +0 -139
  438. package/lib/focus-ring.tsx +0 -46
  439. package/lib/goo-indicator.tsx +0 -261
  440. package/lib/icon-context.tsx +0 -310
  441. package/lib/inert.ts +0 -22
  442. package/lib/morph-layers.tsx +0 -102
  443. package/lib/morph-part.tsx +0 -49
  444. package/lib/popup.ts +0 -52
  445. package/lib/reduced-motion.ts +0 -19
  446. package/lib/row-index.tsx +0 -29
  447. package/lib/row-order.tsx +0 -126
  448. package/lib/scroll-column.tsx +0 -273
  449. package/lib/shape-context.tsx +0 -138
  450. package/lib/shape-radius.ts +0 -67
  451. package/lib/size-context.tsx +0 -66
  452. package/lib/size-scale.ts +0 -115
  453. package/lib/slot.ts +0 -115
  454. package/lib/springs.ts +0 -62
  455. package/lib/surface-classes.ts +0 -58
  456. package/lib/surface-context.tsx +0 -21
  457. package/lib/use-controllable-state.ts +0 -44
  458. package/lib/use-fluid-hover.ts +0 -541
  459. package/lib/use-is-mobile.ts +0 -25
  460. package/lib/use-keyboard-nav-gate.ts +0 -45
  461. package/lib/use-merge-split.tsx +0 -209
  462. package/lib/use-morph.ts +0 -557
  463. package/lib/use-touch-primary.tsx +0 -43
  464. package/lib/utils.ts +0 -37
  465. package/preset.ts +0 -199
  466. package/primitives/code/examples.mdx +0 -27
  467. package/primitives/code/index.tsx +0 -80
  468. package/primitives/craft/demos.tsx +0 -173
  469. package/primitives/craft/examples.mdx +0 -142
  470. package/primitives/craft/index.tsx +0 -76
  471. package/primitives/fluid-hover/examples.mdx +0 -84
  472. package/primitives/fluid-hover/index.tsx +0 -316
  473. package/primitives/morph/examples.mdx +0 -139
  474. package/primitives/morph/index.tsx +0 -192
  475. package/primitives/motion/examples.mdx +0 -100
  476. package/primitives/motion/index.tsx +0 -160
  477. package/primitives/scroll-area/examples.mdx +0 -58
  478. package/primitives/scroll-area/index.tsx +0 -204
  479. package/primitives/separator/examples.mdx +0 -30
  480. package/primitives/separator/index.tsx +0 -53
  481. package/primitives/sizes/examples.mdx +0 -167
  482. package/primitives/sizes/index.tsx +0 -89
  483. package/primitives/skeleton/examples.mdx +0 -51
  484. package/primitives/skeleton/index.tsx +0 -72
  485. package/primitives/skeleton/skeleton.css +0 -15
  486. package/primitives/surface/examples.mdx +0 -173
  487. package/primitives/surface/index.tsx +0 -109
  488. package/primitives/surface/surface.css +0 -176
  489. /package/dist/shared/{components-3ey0hzpb.js → components-1v7rxytx.js} +0 -0
  490. /package/dist/shared/{components-jcnjay5g.js → components-ezxhrmer.js} +0 -0
@@ -1,510 +0,0 @@
1
- // biome-ignore-all lint: vendored upstream code keeps its own patterns (see the header)
2
- /*
3
- * Ported from Fluid Functionalism — github.com/mickadesign/fluid-functionalism
4
- * `registry/default/menu-item.tsx` @ b3587bdbd83fc66c2a6aae3817ffb856cb09260b
5
- * MIT License © 2026 Micka Touillaud — fluidfunctionalism.com (notice: LICENSE.fluid-functionalism)
6
- * Local modifications:
7
- * - `"use client"` dropped; `framer-motion` → `motion/react`; `@/lib/*` and
8
- * `@/hooks/*` imports rewritten to `../../../lib/*`.
9
- * - Uncontrolled selection: when the surrounding panel owns the selection
10
- * (`defaultCheckedIndex` / `defaultCheckedIndices` on Dropdown or
11
- * Dropdown.Content, `selfManaged` in context), a row with no `checked` prop
12
- * derives it from the panel and toggles the panel's state on activation —
13
- * so a docs example can be interactive with no state of its own. An
14
- * explicit `checked` still wins, and the controlled API is unchanged.
15
- * - `sourceIndex`: the row's authored index, stamped by a filtering panel
16
- * (`Dropdown.Search filter`) that re-indexed the visible rows. Selection is
17
- * keyed on it, fluid hover on the re-indexed `index`.
18
- * - Styling reads DS tokens (AGENTS.md styling): inline
19
- * `fontVariationSettings` → `weight-*`; `duration-80|120|160` and
20
- * tier-length JS durations → `duration-<tier>` / `spring.*`.
21
- * - Inside a popup the row's activation travels as `onClick` in the render
22
- * options, for the primitive, instead of sitting on the render element:
23
- * Base UI's Enter/Space activation calls only the primitive's own `onClick`
24
- * prop, so a keyboard pick used to close the menu without selecting.
25
- * - Children-based rows (shadcn parity): `label` and `index` are optional.
26
- * `children` stand in for the label (a string keeps the weight ghost; any
27
- * other node is laid out as the row's own flex items, svgs sized to the
28
- * ladder's icon); a row with no `index` takes its place in the panel's
29
- * document order (`row-order.tsx`). `inset` pads a row to the icon column,
30
- * `shortcut` adds a trailing `Dropdown.Shortcut`, `onSelect` receives a
31
- * cancelable event (`preventDefault()` keeps the menu open), and the
32
- * panel-owned selection only answers rows with an authored `index`.
33
- * - `kind` / `value` (internal): `Dropdown.CheckboxItem` and
34
- * `Dropdown.RadioItem` force the selection primitive and hand the radio its
35
- * real value; their checked rows report to the panel (`reportChecked`) for
36
- * the merged selection background.
37
- * - `DropdownContextValue` gains `pin` (a submenu trigger keeps the panel's
38
- * highlight while its submenu is open) and `reportChecked`.
39
- * - `render` / `asChild` (`lib/slot.ts`): the row becomes the given element
40
- * (a link, a router `Link`), keeping its own props and ref; its children are
41
- * the row's content. In the inline panel Enter and Space click it once, so a
42
- * link navigates.
43
- * - `textValue`: the typeahead text of a row whose content is more than a
44
- * string; it goes to the primitive's `label`.
45
- */
46
-
47
- import { AnimatePresence, motion } from 'motion/react'
48
- import {
49
- createContext,
50
- createElement,
51
- forwardRef,
52
- type HTMLAttributes,
53
- type ReactElement,
54
- type ReactNode,
55
- type Ref,
56
- useContext,
57
- useEffect,
58
- useRef,
59
- version,
60
- } from 'react'
61
- import type { IconComponent } from '../../../lib/icon-context'
62
- import { useRowSlot } from '../../../lib/row-order'
63
- import { shapeMap } from '../../../lib/shape-context'
64
- import { useSize } from '../../../lib/size-context'
65
- import { slotRender } from '../../../lib/slot'
66
- import { spring } from '../../../lib/springs'
67
- import { useRegisterFluidHoverItem } from '../../../lib/use-fluid-hover'
68
- import { cn } from '../../../lib/utils'
69
-
70
- // MenuItem is only used inside Dropdown, which opts out of the global pill
71
- // shape — see index.tsx for the rationale.
72
- const shape = shapeMap.rounded
73
-
74
- const REACT_19 = parseInt(version, 10) >= 19
75
-
76
- /** An element's ref: `props.ref` on React 19, where `element.ref` warns on access; `element.ref` before (where `props.ref` warns). */
77
- function elementRef(element: ReactElement): Ref<HTMLElement> | undefined {
78
- if (REACT_19) return (element.props as { ref?: Ref<HTMLElement> }).ref
79
- return (element as ReactElement & { ref?: Ref<HTMLElement> }).ref
80
- }
81
-
82
- // ---------------------------------------------------------------------------
83
- // Dropdown context — the single shared context for every Dropdown build.
84
- //
85
- // It lives here rather than in the dropdown module so that (a) MenuItem stays
86
- // primitive-free and self-contained, and (b) dropdowns built on different
87
- // primitives (Radix, Base UI) can render side by side — each provides this
88
- // same context object, so MenuItem resolves whichever provider actually
89
- // wraps it. The dropdown module re-exports useDropdown from here, keeping
90
- // its public API unchanged.
91
- // ---------------------------------------------------------------------------
92
-
93
- /** What MenuItem hands to the popup's primitive wrapper. `element` is the
94
- * styled row div (visuals + fluid hover registration, no children); `children`
95
- * is the row content (icon, label, check). The dropdown wraps them in its
96
- * own Item / RadioItem primitive, so MenuItem itself stays primitive-free. */
97
- export interface MenuItemRenderOptions {
98
- /** Radio-style option (boolean `checked` on MenuItem) vs plain action item. */
99
- radio: boolean
100
- /** Checkbox-style option: a boolean `checked` inside a multiple-selection
101
- * dropdown (`checkedIndices`). Takes precedence over `radio`. */
102
- checkbox: boolean
103
- /** The item's checked state (radio and checkbox items). */
104
- checked?: boolean
105
- /** The radio value: the item's index, or a `Dropdown.RadioItem`'s own value. */
106
- value: unknown
107
- disabled?: boolean
108
- /** Typeahead text. Undefined for a children-based row: the primitive reads its text content. */
109
- label?: string
110
- closeOnClick: boolean
111
- /** The row's activation. It goes on the primitive, not on `element`: Base
112
- * UI's Enter/Space activation calls the primitive's own `onClick` prop and
113
- * never sees a handler on the render element. */
114
- onClick?: (e: React.MouseEvent<HTMLDivElement>) => void
115
- element: ReactElement
116
- children: ReactNode
117
- }
118
-
119
- export interface DropdownContextValue {
120
- registerItem: (index: number, element: HTMLElement | null) => void
121
- activeIndex: number | null
122
- checkedIndex?: number
123
- /** Multiple selection (`checkedIndices` on the dropdown): rows are
124
- * checkbox items and activating one keeps the menu open by default. */
125
- multiple?: boolean
126
- checkedIndices?: number[]
127
- /** True when items render inside a Menu popup (DropdownContent), where the
128
- * primitive's Item / RadioItem own roles, roving highlight, typeahead,
129
- * and activation. MenuItem switches its rendering accordingly. */
130
- inMenu?: boolean
131
- /** Popup-only: wraps a MenuItem's styled div in the dropdown's menu-item
132
- * primitive. Absent in the inline Dropdown panel, where MenuItem renders
133
- * its own ARIA menuitem div. */
134
- renderMenuItem?: (opts: MenuItemRenderOptions) => ReactElement
135
- /** Local addition. The panel owns its selection (`defaultCheckedIndex` /
136
- * `defaultCheckedIndices`), so a row with no `checked` prop takes its
137
- * checked state from `checkedIndex` / `checkedIndices` and toggles the
138
- * panel on activation. */
139
- selfManaged?: boolean
140
- /** Local addition. Toggles the row at an AUTHORED index (see
141
- * `sourceIndex`). Present with `selfManaged`. */
142
- toggleIndex?: (sourceIndex: number) => void
143
- /** Local addition. Keeps the highlight on a row while its submenu is open. */
144
- pin?: (index: number, on: boolean) => void
145
- /** Local addition. A value-checked row (`Dropdown.CheckboxItem`,
146
- * `Dropdown.RadioItem`) reports itself for the merged selection background. */
147
- reportChecked?: (index: number, on: boolean) => void
148
- }
149
-
150
- export const DropdownContext = createContext<DropdownContextValue | null>(null)
151
-
152
- export function useDropdown() {
153
- const ctx = useContext(DropdownContext)
154
- if (!ctx) throw new Error('useDropdown must be used within a Dropdown')
155
- return ctx
156
- }
157
-
158
- /** Null-safe context read for callers that render outside a provider. */
159
- export function useDropdownMaybe() {
160
- return useContext(DropdownContext)
161
- }
162
-
163
- /* `inset` swaps the row's padding for one that starts at the label column of
164
- a row with an icon: the ladder's padding + icon + gap (8+16+8, 6+14+4). */
165
- export const INSET_PX = { default: 'pl-8 pr-2', compact: 'pl-6 pr-1.5' } as const
166
- /* Children-based rows lay their nodes out as the row's own flex items; a
167
- bare svg among them takes the ladder's icon size. */
168
- const FREEFORM_SVG = {
169
- default: '[&>svg]:size-4 [&>svg]:shrink-0',
170
- compact: '[&>svg]:size-3.5 [&>svg]:shrink-0',
171
- } as const
172
-
173
- interface MenuItemProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onSelect'> {
174
- /** Optional leading icon. When omitted, the row renders text-only with no
175
- * reserved icon column. */
176
- icon?: IconComponent
177
- /** The row text, also its typeahead text and what a `Dropdown.Search filter` matches. Omit it to pass the row's content as `children`. */
178
- label?: string
179
- /** Position among the panel's rows, for the index-based selection (`checkedIndex`). Omitted, the row takes its place in document order. */
180
- index?: number
181
- /** The row's content when there is no `label`: text, or any nodes (an svg among them takes the icon size). */
182
- children?: ReactNode
183
- /** When a boolean, the item is a radio-style option (role="menuitemradio"
184
- * with aria-checked). When undefined, it is a plain action item
185
- * (role="menuitem"), unless the panel owns the selection — then the row
186
- * reads its checked state off the panel and toggles it on activation. */
187
- checked?: boolean
188
- /** Called when the row is picked, by pointer or keyboard. Call `event.preventDefault()` to keep the menu open. */
189
- onSelect?: (event: Event) => void
190
- /** Dims the row; the pointer and the keyboard skip it. Defaults to `false`. */
191
- disabled?: boolean
192
- /** Popup-only (inside DropdownContent): whether activating the item closes
193
- * the menu. Ignored in the inline Dropdown panel. Defaults to `true` (`false` in multiple selection). */
194
- closeOnClick?: boolean
195
- /** Indents the row to the label column of rows with an icon. Defaults to `false`. */
196
- inset?: boolean
197
- /** A keyboard shortcut shown muted at the row's end, e.g. `⌘K` (see Dropdown.Shortcut). */
198
- shortcut?: ReactNode
199
- /** Typeahead text for a row whose content is more than a string (an icon beside markup): the key a press matches while the menu is open. Defaults to `label`, else the row's text `children`. */
200
- textValue?: string
201
- /** The element that becomes the row, e.g. a link: `render={<a href="/docs" />}`. Its own props and ref are kept, the row's classes and handlers are added, and its children are the row's content. */
202
- render?: ReactElement
203
- /** Compose onto the single child instead of `render`: `<Dropdown.Item asChild><a href="/docs">Docs</a></Dropdown.Item>`. Defaults to `false`. */
204
- asChild?: boolean
205
- /** Internal: the row's authored index, stamped by a filtering panel that
206
- * re-indexed the visible rows. Selection is keyed on it. */
207
- sourceIndex?: number
208
- /** Internal: the selection primitive a `Dropdown.CheckboxItem` / `Dropdown.RadioItem` forces. */
209
- kind?: 'checkbox' | 'radio'
210
- /** Internal: a `Dropdown.RadioItem`'s value. */
211
- value?: unknown
212
- /** Internal: keeps the panel's highlight on the row (a `Dropdown.SubTrigger` whose submenu is open). */
213
- pinned?: boolean
214
- }
215
-
216
- interface DropdownShortcutProps extends HTMLAttributes<HTMLElement> {
217
- /** The keys, e.g. `⇧⌘P`. */
218
- children?: ReactNode
219
- /** Extra classes. */
220
- className?: string
221
- }
222
-
223
- /** A muted caption at the end of a row: the row's keyboard shortcut. */
224
- const DropdownShortcut = forwardRef<HTMLElement, DropdownShortcutProps>(({ className, ...props }, ref) => {
225
- const compact = useSize().variant === 'compact'
226
- return (
227
- <kbd
228
- ref={ref}
229
- className={cn(
230
- 'ml-auto shrink-0 pl-4 font-sans text-muted-foreground',
231
- compact ? 'text-caption-compact' : 'text-caption',
232
- className,
233
- )}
234
- {...props}
235
- />
236
- )
237
- })
238
-
239
- DropdownShortcut.displayName = 'DropdownShortcut'
240
-
241
- const MenuItem = forwardRef<HTMLDivElement, MenuItemProps>(
242
- (
243
- {
244
- icon: Icon,
245
- label,
246
- textValue,
247
- render,
248
- asChild,
249
- index: indexProp,
250
- children: childrenProp,
251
- checked,
252
- onSelect,
253
- disabled,
254
- closeOnClick,
255
- inset,
256
- shortcut,
257
- sourceIndex,
258
- kind,
259
- value,
260
- pinned,
261
- className,
262
- onClick,
263
- ...props
264
- },
265
- ref,
266
- ) => {
267
- const internalRef = useRef<HTMLDivElement>(null)
268
- const slot = slotRender(render, asChild, childrenProp)
269
- // The slot element's own children are the row's content.
270
- const children = slot ? (slot.props as { children?: ReactNode }).children : childrenProp
271
- const hasMounted = useRef(false)
272
- const {
273
- registerItem,
274
- activeIndex,
275
- checkedIndex,
276
- multiple,
277
- checkedIndices,
278
- renderMenuItem,
279
- selfManaged,
280
- toggleIndex,
281
- reportChecked,
282
- pin,
283
- } = useDropdown()
284
- const { index, firstRow } = useRowSlot(internalRef, indexProp)
285
- // The panel's index-keyed selection answers only rows written with an index.
286
- const authored = indexProp !== undefined
287
-
288
- // Uncontrolled panels answer for rows that brought no `checked` of their
289
- // own; a row that did keeps it.
290
- const panelChecked = multiple ? (checkedIndices?.includes(indexProp ?? -1) ?? false) : checkedIndex === indexProp
291
- const isChecked = checked ?? (selfManaged && authored ? panelChecked : undefined)
292
- const isCheckbox = kind ? kind === 'checkbox' : !!multiple && typeof isChecked === 'boolean'
293
- const isRadio = kind ? kind === 'radio' : !isCheckbox && typeof isChecked === 'boolean'
294
-
295
- useRegisterFluidHoverItem(registerItem, index, internalRef)
296
-
297
- useEffect(() => {
298
- if (!kind || !isChecked || index === undefined || !reportChecked) return
299
- reportChecked(index, true)
300
- return () => reportChecked(index, false)
301
- }, [kind, isChecked, index, reportChecked])
302
-
303
- useEffect(() => {
304
- if (!pinned || index === undefined || !pin) return
305
- pin(index, true)
306
- return () => pin(index, false)
307
- }, [pinned, index, pin])
308
-
309
- useEffect(() => {
310
- hasMounted.current = true
311
- }, [])
312
-
313
- const isActive = index !== undefined && activeIndex === index
314
- const skipAnimation = !hasMounted.current
315
- const sizeClasses = useSize()
316
- const text = label ?? (typeof children === 'string' ? children : undefined)
317
- const freeform = label === undefined && text === undefined
318
- const lit = isActive || isChecked
319
-
320
- const slotRef = slot ? elementRef(slot) : undefined
321
- const mergeRef = (node: HTMLDivElement | null) => {
322
- ;(internalRef as React.MutableRefObject<HTMLDivElement | null>).current = node
323
- for (const target of [ref, slotRef]) {
324
- if (typeof target === 'function') target(node)
325
- else if (target) (target as React.MutableRefObject<HTMLDivElement | null>).current = node
326
- }
327
- }
328
-
329
- // The row element: a div, or the slot element with the row's props on top of its own.
330
- // The caller's own props come last, as they always did.
331
- const rowElement = (extra?: object) => {
332
- const rowProps = {
333
- ref: mergeRef,
334
- 'data-fluid-hover-index': index,
335
- ...(label !== undefined && { 'aria-label': label }),
336
- ...extra,
337
- ...props,
338
- }
339
- if (!slot) return <div {...rowProps} className={itemClassName} />
340
- // Built without the slot's own children, which would win over the row's content in the primitive.
341
- const { children: _content, ...slotProps } = slot.props as { children?: ReactNode; className?: string }
342
- return createElement(slot.type, { ...slotProps, ...rowProps, className: cn(slotProps.className, itemClassName) })
343
- }
344
-
345
- // Selection is keyed on the authored index, which survives a filtering
346
- // panel's re-indexing of the visible rows. Returns whether the consumer
347
- // asked to keep the menu open.
348
- const activate = () => {
349
- const event = new Event('select', { cancelable: true })
350
- onSelect?.(event)
351
- if (selfManaged && authored && !kind) toggleIndex?.(sourceIndex ?? indexProp)
352
- return event.defaultPrevented
353
- }
354
-
355
- const handleActivate = disabled
356
- ? undefined
357
- : (e: React.MouseEvent<HTMLDivElement>) => {
358
- onClick?.(e)
359
- // Base UI's own close runs after this handler unless prevented.
360
- if (activate()) (e as { preventBaseUIHandler?: () => void }).preventBaseUIHandler?.()
361
- }
362
-
363
- const itemClassName = cn(
364
- // Fixed height (was py-2 around a 19.5px line box ≈ 35.5px) so the
365
- // text-box trim on the label doesn't shrink the row. shrink-0 because
366
- // menu popups are max-height flex columns — without it a long list
367
- // compresses rows to fit instead of scrolling.
368
- `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`,
369
- freeform && [
370
- sizeClasses.text,
371
- FREEFORM_SVG[sizeClasses.variant],
372
- 'min-w-0 transition-[color,font-variation-settings] duration-fast',
373
- lit ? 'text-foreground' : 'text-muted-foreground',
374
- isChecked ? 'weight-semibold' : 'weight-normal',
375
- ],
376
- disabled && 'opacity-50 pointer-events-none',
377
- className,
378
- )
379
-
380
- const content = (
381
- <>
382
- {Icon && (
383
- <span className="inline-grid">
384
- <span className="col-start-1 row-start-1 invisible">
385
- <Icon size={sizeClasses.icon} strokeWidth={2} />
386
- </span>
387
- <Icon
388
- size={sizeClasses.icon}
389
- strokeWidth={lit ? 2 : 1.5}
390
- className={cn(
391
- 'col-start-1 row-start-1 transition-[color,stroke-width] duration-fast',
392
- lit ? 'text-foreground' : 'text-muted-foreground',
393
- )}
394
- />
395
- </span>
396
- )}
397
- {text !== undefined && (
398
- // Both stacked spans carry the text-box trim so the invisible bold
399
- // sizer and the visible label keep identical boxes.
400
- <span className={cn('inline-grid min-w-0 flex-1', sizeClasses.text)}>
401
- <span
402
- className="col-start-1 row-start-1 invisible truncate [text-box:trim-both_cap_alphabetic] weight-semibold"
403
- aria-hidden="true"
404
- >
405
- {text}
406
- </span>
407
- <span
408
- className={cn(
409
- 'col-start-1 row-start-1 truncate transition-[color,font-variation-settings] duration-fast [text-box:trim-both_cap_alphabetic]',
410
- lit ? 'text-foreground' : 'text-muted-foreground',
411
- isChecked ? 'weight-semibold' : 'weight-normal',
412
- )}
413
- >
414
- {text}
415
- </span>
416
- </span>
417
- )}
418
- {label !== undefined || freeform ? children : null}
419
- {shortcut != null && <DropdownShortcut>{shortcut}</DropdownShortcut>}
420
- <AnimatePresence>
421
- {isChecked && (
422
- <motion.svg
423
- key="check"
424
- width={sizeClasses.icon}
425
- height={sizeClasses.icon}
426
- viewBox="0 0 24 24"
427
- fill="none"
428
- stroke="currentColor"
429
- strokeWidth={2}
430
- strokeLinecap="round"
431
- strokeLinejoin="round"
432
- className={cn('text-foreground shrink-0', freeform && shortcut == null && 'ml-auto')}
433
- initial={{ opacity: 1 }}
434
- animate={{ opacity: 1 }}
435
- exit={{ opacity: 1 }}
436
- >
437
- <motion.path
438
- d="M4 12L9 17L20 6"
439
- initial={{ pathLength: skipAnimation ? 1 : 0 }}
440
- animate={{
441
- pathLength: 1,
442
- transition: { duration: spring.fast.duration, ease: 'easeOut' },
443
- }}
444
- exit={{
445
- pathLength: 0,
446
- transition: { duration: 0.04, ease: 'easeIn' },
447
- }}
448
- />
449
- </motion.svg>
450
- )}
451
- </AnimatePresence>
452
- </>
453
- )
454
-
455
- if (renderMenuItem) {
456
- // Inside DropdownContent, the menu-item primitive (supplied by the
457
- // surrounding DropdownContent through context) owns the role,
458
- // aria-checked, tabIndex, roving highlight, typeahead, and Enter/Space/
459
- // click activation (handleActivate rides on the primitive, whose
460
- // keyboard activation calls it too). The styled div carries the Fluid
461
- // Functionalism visuals and the fluid-hover registration; MenuItem
462
- // itself imports no primitive.
463
- return renderMenuItem({
464
- radio: isRadio,
465
- checkbox: isCheckbox,
466
- checked: isChecked,
467
- value: kind === 'radio' ? value : index,
468
- disabled,
469
- label: textValue ?? text,
470
- // Toggling one of several stays open; picking one of one closes.
471
- closeOnClick: closeOnClick ?? (kind ? kind === 'radio' : !multiple),
472
- onClick: handleActivate,
473
- element: rowElement(),
474
- children: content,
475
- })
476
- }
477
-
478
- // The roving tab stop: the checked row, else the first one.
479
- const tabStop = authored ? (checkedIndex ?? checkedIndices?.[0] ?? 0) : firstRow
480
- const slotOnClick = (slot?.props as { onClick?: (e: React.MouseEvent<HTMLDivElement>) => void } | undefined)
481
- ?.onClick
482
- return rowElement({
483
- // Disabled items are never the roving tab stop.
484
- tabIndex: !disabled && index === tabStop ? 0 : -1,
485
- role: isCheckbox ? 'menuitemcheckbox' : isRadio ? 'menuitemradio' : 'menuitem',
486
- 'aria-checked': typeof isChecked === 'boolean' ? isChecked : undefined,
487
- 'aria-disabled': disabled || undefined,
488
- onClick: (e: React.MouseEvent<HTMLDivElement>) => {
489
- slotOnClick?.(e)
490
- handleActivate?.(e)
491
- },
492
- onKeyDown: (e: React.KeyboardEvent<HTMLDivElement>) => {
493
- if (disabled) return
494
- if (e.key === ' ' || e.key === 'Enter') {
495
- e.preventDefault()
496
- // A slot element is clicked once: a link navigates, its own handlers run.
497
- if (slot) e.currentTarget.click()
498
- else activate()
499
- }
500
- },
501
- children: content,
502
- })
503
- },
504
- )
505
-
506
- MenuItem.displayName = 'MenuItem'
507
-
508
- export type { DropdownShortcutProps, MenuItemProps }
509
- export { DropdownShortcut, MenuItem }
510
- export default MenuItem