@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,494 +0,0 @@
1
- /*
2
- * Ported from Fluid Functionalism — github.com/mickadesign/fluid-functionalism
3
- * `registry/base/tabs.tsx` @ b3587bdbd83fc66c2a6aae3817ffb856cb09260b
4
- * MIT License © 2026 Micka Touillaud — fluidfunctionalism.com (notice: LICENSE.fluid-functionalism)
5
- * Local modifications: `"use client"` dropped; `@/lib/*` and `@/hooks/*`
6
- * imports rewritten to `../../../lib/*` (`SizeProvider` to
7
- * `../../../primitives/sizes`), `framer-motion` to `motion/react`; `defaultSelectedIndex` added as the index-mode twin of the
8
- * existing value-mode `defaultValue` (it only seeds the first render, like
9
- * `defaultValue`); modo docs — TSDoc with FF's docs/API text, `Tabs.List` /
10
- * `Tabs.Item` / `Tabs.Panel` statics (typed via a cast on the root), default
11
- * export (upstream has none).
12
- * Styling reads DS tokens (AGENTS.md styling): inline `fontVariationSettings`
13
- * → `weight-*`; the hex focus-ring fallback → `ring-focus-ring` /
14
- * `border-focus-ring`; `duration-80|120|160` and tier-length JS durations →
15
- * `duration-<tier>` / `spring.*`.
16
- * The active indicator and the hover pill are `GooIndicator`s
17
- * (`lib/goo-indicator.tsx`, local): they melt from tab to tab instead of
18
- * sliding; the hover pill now always returns to the active tab as it fades.
19
- * - `Tabs.Item` `label` takes any node (a counter, a badge) besides a string;
20
- * the weight ghost-span keeps holding the width, its hidden copy `inert`
21
- * (`markInert` from `lib/inert.ts`).
22
- * `href` renders the tab as an anchor (link tabs) through Base UI's `render`.
23
- */
24
-
25
- import { Tabs as TabsPrimitive } from '@base-ui/react/tabs'
26
- import { AnimatePresence, motion } from 'motion/react'
27
- import {
28
- Children,
29
- type ComponentPropsWithoutRef,
30
- cloneElement,
31
- createContext,
32
- type ForwardRefExoticComponent,
33
- forwardRef,
34
- isValidElement,
35
- type ReactNode,
36
- type RefAttributes,
37
- useCallback,
38
- useContext,
39
- useEffect,
40
- useLayoutEffect,
41
- useRef,
42
- useState,
43
- } from 'react'
44
- import { GooIndicator } from '../../../lib/goo-indicator'
45
- import type { IconComponent } from '../../../lib/icon-context'
46
- import { markInert } from '../../../lib/inert'
47
- import { useShape } from '../../../lib/shape-context'
48
- import { type SizeVariant, useSize } from '../../../lib/size-context'
49
- import { spring } from '../../../lib/springs'
50
- import { SURFACE_BG, SURFACE_SHADOW } from '../../../lib/surface-classes'
51
- import { useSurface } from '../../../lib/surface-context'
52
- import { useFluidHover } from '../../../lib/use-fluid-hover'
53
- import { cn } from '../../../lib/utils'
54
- import { SizeProvider } from '../../../primitives/sizes'
55
-
56
- /* ─────────────────────── Contexts ─────────────────────── */
57
-
58
- interface TabsValueOrderContextValue {
59
- valueOrder: string[]
60
- setValueOrder: (order: string[]) => void
61
- selectedValue: string | undefined
62
- }
63
-
64
- const TabsValueOrderContext = createContext<TabsValueOrderContextValue | null>(null)
65
-
66
- interface TabsListContextValue {
67
- registerTab: (index: number, value: string, el: HTMLElement | null) => void
68
- hoveredIndex: number | null
69
- selectedValue: string | undefined
70
- setOptimisticIdx: (index: number) => void
71
- }
72
-
73
- const TabsListContext = createContext<TabsListContextValue | null>(null)
74
-
75
- function useTabsList() {
76
- const ctx = useContext(TabsListContext)
77
- if (!ctx) throw new Error('TabItem must be used within a TabsList')
78
- return ctx
79
- }
80
-
81
- /* ─────────────────────── Tabs (Root) ─────────────────────── */
82
-
83
- interface TabsProps
84
- extends Omit<
85
- ComponentPropsWithoutRef<typeof TabsPrimitive.Root>,
86
- 'onValueChange' | 'value' | 'defaultValue' | 'onSelect'
87
- > {
88
- /** Controlled active tab value. Takes precedence over selectedIndex. */
89
- value?: string
90
- /** Called when the active tab changes. */
91
- onValueChange?: (value: string) => void
92
- /** Index-based controlled alternative. */
93
- selectedIndex?: number
94
- /** Called with the new index when the active tab changes. */
95
- onSelect?: (index: number) => void
96
- /** Default active tab for uncontrolled usage. Defaults to the first tab. */
97
- defaultValue?: string
98
- /** Index-based uncontrolled alternative: the tab active on first render. Ignored when `defaultValue` is set. */
99
- defaultSelectedIndex?: number
100
- /** Pins the segmented control to one step of the size ladder (default 36px outer, compact 28px). Defaults to the surrounding SizeProvider. */
101
- size?: SizeVariant
102
- /** Tabs.List and Tabs.Panel children. */
103
- children?: ReactNode
104
- }
105
-
106
- type TabsComponent = ForwardRefExoticComponent<TabsProps & RefAttributes<HTMLDivElement>> & {
107
- List: typeof TabsList
108
- Item: typeof TabItem
109
- Panel: typeof TabPanel
110
- }
111
-
112
- /**
113
- * Segmented control tabs with sliding active indicator, fluid hover, and
114
- * spring animations.
115
- *
116
- * Built on Base UI Tabs: `Tabs` owns the selection, `Tabs.List` draws the
117
- * segmented track with an elevated indicator that melts toward the active tab
118
- * like a drop (lifted three surface levels above whatever it sits on; see the
119
- * liquid indicators in Morph) and a translucent hover pill that drips out of
120
- * it, and `Tabs.Panel` shows the content of the active tab. Arrow keys
121
- * move and activate. Select by value — `defaultValue` uncontrolled, `value` +
122
- * `onValueChange` controlled — or by index with `defaultSelectedIndex` /
123
- * `selectedIndex` + `onSelect`.
124
- *
125
- * Statics:
126
- * - `Tabs.List` — the segmented track holding the tabs.
127
- * - `Tabs.Item` — one tab: `value`, `label` (text, or a node such as a
128
- * label with a counter), optional `icon`, and `href` to render it as a link.
129
- * - `Tabs.Panel` — content shown while the tab with the same `value` is active.
130
- *
131
- * @example {@include ./examples.mdx}
132
- */
133
- const Tabs = forwardRef<HTMLDivElement, TabsProps>(
134
- (
135
- { value, onValueChange, selectedIndex, onSelect, defaultValue, defaultSelectedIndex, size, children, ...props },
136
- ref,
137
- ) => {
138
- const [valueOrder, setValueOrder] = useState<string[]>([])
139
- const [uncontrolledValue, setUncontrolledValue] = useState<string | undefined>(defaultValue)
140
- const updateValueOrder = useCallback((order: string[]) => {
141
- setValueOrder(current => {
142
- if (current.length === order.length && current.every((v, i) => v === order[i])) {
143
- return current
144
- }
145
- return order
146
- })
147
- }, [])
148
-
149
- // Resolve value: explicit value > selectedIndex lookup > uncontrolled state.
150
- // Uncontrolled with no defaultValue falls back to the first tab so the
151
- // FF layer's selectedValue matches what the primitive shows.
152
- // Local: ...or to the `defaultSelectedIndex` tab, when given.
153
- const resolvedValue =
154
- value ??
155
- (selectedIndex != null ? valueOrder[selectedIndex] : (uncontrolledValue ?? valueOrder[defaultSelectedIndex ?? 0]))
156
-
157
- // Base UI passes (value, eventDetails); we only need value.
158
- const handleValueChange = useCallback(
159
- (newValue: unknown) => {
160
- const v = newValue as string
161
- if (value === undefined && selectedIndex == null) {
162
- setUncontrolledValue(v)
163
- }
164
- onValueChange?.(v)
165
- if (onSelect) {
166
- const idx = valueOrder.indexOf(v)
167
- if (idx !== -1) onSelect(idx)
168
- }
169
- },
170
- [onValueChange, onSelect, valueOrder, value, selectedIndex],
171
- )
172
-
173
- const root = (
174
- <TabsValueOrderContext.Provider
175
- value={{
176
- valueOrder,
177
- setValueOrder: updateValueOrder,
178
- selectedValue: resolvedValue,
179
- }}
180
- >
181
- {/*
182
- Always controlled: Base UI's useControlled logs a dev warning when
183
- value flips undefined → defined. valueOrder is empty on the first
184
- commit, so fall back to an empty-string sentinel — TabsList's
185
- layout effect populates valueOrder pre-paint, so the corrected
186
- value lands before anything is visible.
187
- */}
188
- <TabsPrimitive.Root ref={ref} value={resolvedValue ?? ''} onValueChange={handleValueChange} {...props}>
189
- {children}
190
- </TabsPrimitive.Root>
191
- </TabsValueOrderContext.Provider>
192
- )
193
-
194
- // A size prop pins the whole compound (list + items) to one ladder step.
195
- return size ? <SizeProvider size={size}>{root}</SizeProvider> : root
196
- },
197
- ) as TabsComponent
198
-
199
- Tabs.displayName = 'Tabs'
200
-
201
- /* ─────────────────────── TabsList ─────────────────────── */
202
-
203
- type TabsListProps = ComponentPropsWithoutRef<typeof TabsPrimitive.List>
204
-
205
- const TabsList = forwardRef<HTMLDivElement, TabsListProps>(({ children, className, ...props }, ref) => {
206
- const containerRef = useRef<HTMLDivElement>(null)
207
- const isMouseInside = useRef(false)
208
- const shape = useShape()
209
- const sizeClasses = useSize()
210
- const substrate = useSurface()
211
- const indicatorLevel = Math.min(substrate + 3, 8)
212
- const valueOrderCtx = useContext(TabsValueOrderContext)
213
- const [optimisticIdx, setOptimisticIdx] = useState<number | null>(null)
214
-
215
- const values = Children.toArray(children)
216
- .filter(isValidElement)
217
- .map(child => (child.props as { value?: string }).value)
218
- .filter((v): v is string => typeof v === 'string')
219
- const valueOrderKey = values.join(',')
220
- const setValueOrder = valueOrderCtx?.setValueOrder
221
-
222
- useLayoutEffect(() => {
223
- setValueOrder?.(values)
224
- }, [setValueOrder, valueOrderKey])
225
-
226
- const {
227
- activeIndex: hoveredIndex,
228
- setActiveIndex: setHoveredIndex,
229
- itemRects,
230
- handlers,
231
- registerItem,
232
- measureItems,
233
- } = useFluidHover(containerRef, { axis: 'x' })
234
-
235
- const registerTab = useCallback(
236
- (index: number, _value: string, el: HTMLElement | null) => {
237
- registerItem(index, el)
238
- },
239
- [registerItem],
240
- )
241
-
242
- useEffect(() => {
243
- measureItems()
244
- }, [measureItems, children])
245
-
246
- const handleMouseMove = useCallback(
247
- (e: React.MouseEvent) => {
248
- isMouseInside.current = true
249
- handlers.onMouseMove(e)
250
- },
251
- [handlers],
252
- )
253
-
254
- const handleMouseLeave = useCallback(() => {
255
- isMouseInside.current = false
256
- handlers.onMouseLeave()
257
- }, [handlers])
258
-
259
- const [focusedIndex, setFocusedIndex] = useState<number | null>(null)
260
- const selectedValue = valueOrderCtx?.selectedValue
261
- const selectedIdx = selectedValue !== undefined ? values.indexOf(selectedValue) : -1
262
-
263
- useEffect(() => {
264
- setOptimisticIdx(selectedIdx >= 0 ? selectedIdx : null)
265
- }, [selectedIdx])
266
-
267
- const activeSelectedIdx = optimisticIdx
268
- const selectedRect = activeSelectedIdx !== null ? itemRects[activeSelectedIdx] : null
269
- const hoverRect = hoveredIndex !== null ? itemRects[hoveredIndex] : null
270
- const focusRect = focusedIndex !== null ? itemRects[focusedIndex] : null
271
- const isHoveringSelected = hoveredIndex === activeSelectedIdx
272
- const isHovering = hoveredIndex !== null && !isHoveringSelected
273
-
274
- const indexedChildren = Children.map(children, (child, i) => {
275
- // Skip plain DOM elements — injecting _index into e.g. a <div>
276
- // triggers React's unknown-prop warning.
277
- if (isValidElement(child) && typeof child.type !== 'string') {
278
- return cloneElement(child, { _index: i } as Record<string, unknown>)
279
- }
280
- return child
281
- })
282
-
283
- return (
284
- <TabsListContext.Provider
285
- value={{
286
- registerTab,
287
- hoveredIndex,
288
- selectedValue,
289
- setOptimisticIdx,
290
- }}
291
- >
292
- <TabsPrimitive.List
293
- // Match Radix's `activationMode="automatic"` — arrow keys move + activate.
294
- activateOnFocus
295
- ref={node => {
296
- ;(containerRef as React.MutableRefObject<HTMLDivElement | null>).current = node
297
- if (typeof ref === 'function') ref(node)
298
- else if (ref) (ref as React.MutableRefObject<HTMLDivElement | null>).current = node
299
- }}
300
- onMouseMove={handleMouseMove}
301
- onMouseLeave={handleMouseLeave}
302
- onFocus={e => {
303
- const trigger = (e.target as HTMLElement).closest('[role="tab"]')
304
- if (!trigger) return
305
- const indexAttr = trigger.getAttribute('data-fluid-hover-index')
306
- if (indexAttr != null) {
307
- const idx = Number(indexAttr)
308
- setHoveredIndex(idx)
309
- setFocusedIndex((e.target as HTMLElement).matches(':focus-visible') ? idx : null)
310
- }
311
- }}
312
- onBlur={e => {
313
- if (containerRef.current?.contains(e.relatedTarget as Node)) return
314
- setFocusedIndex(null)
315
- if (isMouseInside.current) return
316
- setHoveredIndex(null)
317
- }}
318
- className={cn(
319
- // segmentPad + segmentItem add up to the ladder's control height
320
- // (36px default, 28px compact) so the segmented control's outer
321
- // box lines up with buttons, selects, and inputs beside it.
322
- 'relative inline-flex items-center select-none bg-well',
323
- sizeClasses.segmentPad,
324
- shape.container,
325
- className,
326
- )}
327
- {...props}
328
- >
329
- {selectedRect && (
330
- <GooIndicator
331
- rect={selectedRect}
332
- className={cn(SURFACE_BG[indicatorLevel], shape.bg)}
333
- shadow={SURFACE_SHADOW[indicatorLevel]}
334
- opacity={isHovering ? 0.85 : 1}
335
- />
336
- )}
337
-
338
- {/* the hover pill rests on the active tab, so it drips back into it as it fades */}
339
- {selectedRect && (
340
- <GooIndicator
341
- rect={isHovering && hoverRect ? hoverRect : selectedRect}
342
- className={cn('bg-hover', shape.bg)}
343
- transition={spring.fast}
344
- opacity={isHovering ? 0.4 : 0}
345
- />
346
- )}
347
-
348
- {/* Focus ring */}
349
- <AnimatePresence>
350
- {focusRect && (
351
- <motion.div
352
- className={cn('absolute pointer-events-none z-20 border border-focus-ring', shape.focusRing)}
353
- initial={false}
354
- animate={{
355
- left: focusRect.left - 2,
356
- top: focusRect.top - 2,
357
- width: focusRect.width + 4,
358
- height: focusRect.height + 4,
359
- }}
360
- exit={{ opacity: 0, transition: spring.fast.exit }}
361
- transition={{
362
- ...spring.fast,
363
- opacity: { duration: spring.fast.duration },
364
- }}
365
- />
366
- )}
367
- </AnimatePresence>
368
-
369
- {indexedChildren}
370
- </TabsPrimitive.List>
371
- </TabsListContext.Provider>
372
- )
373
- })
374
-
375
- TabsList.displayName = 'TabsList'
376
-
377
- /* ─────────────────────── TabItem ─────────────────────── */
378
-
379
- interface TabItemProps extends ComponentPropsWithoutRef<typeof TabsPrimitive.Tab> {
380
- /** The tab's value, matched by `Tabs.Panel` and the root's `value`. */
381
- value: string
382
- /** Leading icon; its stroke thickens while the tab is hovered or active. */
383
- icon?: IconComponent
384
- /** The label: text, or a node such as text with a counter or a badge. */
385
- label: ReactNode
386
- /** Render the tab as an anchor to this URL (link tabs): pressing it follows the link and selects the tab. */
387
- href?: string
388
- /** @internal Auto-assigned by TabsList. */
389
- _index?: number
390
- }
391
-
392
- const TabItem = forwardRef<HTMLButtonElement, TabItemProps>(
393
- ({ value, icon: Icon, label, href, _index = 0, className, onClick, ...props }, ref) => {
394
- const internalRef = useRef<HTMLButtonElement>(null)
395
- const sizeClasses = useSize()
396
- const { registerTab, hoveredIndex, selectedValue, setOptimisticIdx } = useTabsList()
397
-
398
- useEffect(() => {
399
- registerTab(_index, value, internalRef.current)
400
- return () => registerTab(_index, value, null)
401
- }, [_index, value, registerTab])
402
-
403
- const isSelected = selectedValue === value
404
- const isActive = hoveredIndex === _index || isSelected
405
- // A text label trims its box to the cap height; a node (a counter, a badge) lays out as a row.
406
- const text = typeof label === 'string' || typeof label === 'number'
407
- const labelLayout = text ? '[text-box:trim-both_cap_alphabetic]' : 'inline-flex items-center gap-1.5'
408
-
409
- return (
410
- <TabsPrimitive.Tab
411
- // Composed (not spread-overridable): a consumer onClick must not
412
- // replace the optimistic indicator jump.
413
- onClick={e => {
414
- setOptimisticIdx(_index)
415
- onClick?.(e)
416
- }}
417
- ref={node => {
418
- ;(internalRef as React.MutableRefObject<HTMLElement | null>).current = node as HTMLButtonElement | null
419
- if (typeof ref === 'function') ref(node as HTMLButtonElement)
420
- else if (ref)
421
- (ref as React.MutableRefObject<HTMLButtonElement | null>).current = node as HTMLButtonElement | null
422
- }}
423
- value={value}
424
- // Local: link tabs render an anchor (Base UI keeps the tab semantics on it).
425
- // biome-ignore lint/a11y/useAnchorContent: Base UI renders the tab's label into the anchor
426
- {...(href !== undefined && { render: <a href={href} />, nativeButton: false })}
427
- data-fluid-hover-index={_index}
428
- className={cn(
429
- // Fixed height (not py) so the text-box trim below doesn't shrink
430
- // the tab — browsers without text-box support render identically.
431
- 'relative z-10 flex items-center px-3 cursor-pointer bg-transparent border-none outline-none no-underline',
432
- sizeClasses.segmentItem,
433
- sizeClasses.gap,
434
- className,
435
- )}
436
- {...props}
437
- >
438
- {Icon && (
439
- <Icon
440
- size={sizeClasses.icon}
441
- strokeWidth={isActive ? 2 : 1.5}
442
- className={cn(
443
- 'transition-[color,stroke-width] duration-fast',
444
- isActive ? 'text-foreground' : 'text-muted-foreground',
445
- )}
446
- />
447
- )}
448
- {/* Both stacked spans carry the same layout so the invisible bold
449
- sizer and the visible label keep identical boxes. A node label
450
- renders twice too; its hidden copy is inert, so keep it
451
- presentational (text, counters, badges). */}
452
- <span className={cn('inline-grid whitespace-nowrap', sizeClasses.text)}>
453
- <span
454
- className={cn('col-start-1 row-start-1 invisible weight-semibold', labelLayout)}
455
- aria-hidden="true"
456
- ref={text ? undefined : markInert}
457
- >
458
- {label}
459
- </span>
460
- <span
461
- className={cn(
462
- 'col-start-1 row-start-1 transition-[color,font-variation-settings] duration-fast',
463
- labelLayout,
464
- isActive ? 'text-foreground' : 'text-muted-foreground',
465
- isSelected ? 'weight-semibold' : 'weight-normal',
466
- )}
467
- >
468
- {label}
469
- </span>
470
- </span>
471
- </TabsPrimitive.Tab>
472
- )
473
- },
474
- )
475
-
476
- TabItem.displayName = 'TabItem'
477
-
478
- /* ─────────────────────── TabPanel ─────────────────────── */
479
-
480
- interface TabPanelProps extends ComponentPropsWithoutRef<typeof TabsPrimitive.Panel> {
481
- value: string
482
- }
483
-
484
- const TabPanel = forwardRef<HTMLDivElement, TabPanelProps>(({ className, ...props }, ref) => {
485
- return <TabsPrimitive.Panel ref={ref} className={cn('outline-none', className)} {...props} />
486
- })
487
-
488
- TabPanel.displayName = 'TabPanel'
489
-
490
- Object.assign(Tabs, { List: TabsList, Item: TabItem, Panel: TabPanel })
491
-
492
- export type { TabItemProps, TabPanelProps, TabsListProps, TabsProps }
493
- export { TabItem, TabPanel, Tabs, TabsList }
494
- export default Tabs
@@ -1,49 +0,0 @@
1
- import TabsSubtle from './index'
2
- import { Clock, SquareLibrary, Star, Users } from 'lucide-react'
3
-
4
- # Basic
5
-
6
- The pill follows the selected tab; panels swap with it.
7
-
8
- <div className="flex flex-col gap-4 w-full">
9
- <TabsSubtle defaultSelectedIndex={0}>
10
- {['Teamspaces', 'Recents', 'Favorites', 'Shared'].map((label, i) => (
11
- <TabsSubtle.Item key={label} index={i} label={label} />
12
- ))}
13
- {['Teamspaces', 'Recents', 'Favorites', 'Shared'].map((label, i) => (
14
- <TabsSubtle.Panel key={label} index={i}>
15
- <p className="text-body text-muted-foreground px-3">{label} content goes here.</p>
16
- </TabsSubtle.Panel>
17
- ))}
18
- </TabsSubtle>
19
- </div>
20
-
21
- # With Icons
22
-
23
- An `icon` sits ahead of the label and thickens its stroke while its tab is
24
- hovered or selected.
25
-
26
- <div className="flex flex-col gap-4 w-full">
27
- <TabsSubtle defaultSelectedIndex={0}>
28
- <TabsSubtle.Item index={0} icon={SquareLibrary} label="Teamspaces" />
29
- <TabsSubtle.Item index={1} icon={Clock} label="Recents" />
30
- <TabsSubtle.Item index={2} icon={Star} label="Favorites" />
31
- <TabsSubtle.Item index={3} icon={Users} label="Shared" />
32
- <TabsSubtle.Panel index={0}><p className="text-body text-muted-foreground px-3">Teamspaces content goes here.</p></TabsSubtle.Panel>
33
- <TabsSubtle.Panel index={1}><p className="text-body text-muted-foreground px-3">Recents content goes here.</p></TabsSubtle.Panel>
34
- <TabsSubtle.Panel index={2}><p className="text-body text-muted-foreground px-3">Favorites content goes here.</p></TabsSubtle.Panel>
35
- <TabsSubtle.Panel index={3}><p className="text-body text-muted-foreground px-3">Shared content goes here.</p></TabsSubtle.Panel>
36
- </TabsSubtle>
37
- </div>
38
-
39
- # Active Label
40
-
41
- With `activeLabel`, every tab shrinks to its icon and only the selected one
42
- spells itself out.
43
-
44
- <TabsSubtle activeLabel defaultSelectedIndex={0}>
45
- <TabsSubtle.Item index={0} icon={SquareLibrary} label="Teamspaces" />
46
- <TabsSubtle.Item index={1} icon={Clock} label="Recents" />
47
- <TabsSubtle.Item index={2} icon={Star} label="Favorites" />
48
- <TabsSubtle.Item index={3} icon={Users} label="Shared" />
49
- </TabsSubtle>