@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,512 +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/base/tabs-subtle.tsx` @ b3587bdbd83fc66c2a6aae3817ffb856cb09260b
5
- * MIT License © 2026 Micka Touillaud — fluidfunctionalism.com (notice: LICENSE.fluid-functionalism)
6
- * Local modifications: `"use client"` dropped; `@/lib/*` and `@/hooks/*`
7
- * imports rewritten to `../../../lib/*` (`SizeProvider` to
8
- * `../../../primitives/sizes`), `framer-motion` to `motion/react`; uncontrolled mode added — `selectedIndex` and `onSelect` are
9
- * optional, with a `defaultSelectedIndex` twin backed by
10
- * `useControllableState`; panels may now be written inside `<TabsSubtle>` —
11
- * the root partitions its children, renders only the tabs inside the tab list
12
- * and the `TabsSubtlePanel`s as its siblings right after it (the root element
13
- * IS the `role="tablist"`, so panels cannot nest in it), and a panel with no
14
- * `selectedIndex` / `idPrefix` of its own reads both from the TabsSubtle
15
- * context, with the prefix falling back to a `useId()` one; a panel rendered
16
- * outside `<TabsSubtle>` keeps taking them as props, exactly as upstream;
17
- * React 18 types: the tab list's ref write goes through `MutableRefObject`; modo
18
- * docs — TSDoc with FF's docs/API text, `TabsSubtle.Item` / `TabsSubtle.Panel`
19
- * statics (typed via a cast on the root), default export.
20
- * Styling reads DS tokens (AGENTS.md styling): inline `fontVariationSettings`
21
- * → `weight-*`; the hex focus-ring fallback → `ring-focus-ring` /
22
- * `border-focus-ring`; `duration-80|120|160` and tier-length JS durations →
23
- * `duration-<tier>` / `spring.*`.
24
- * The selected and hover pills are `GooIndicator`s (`lib/goo-indicator.tsx`,
25
- * local): they melt from tab to tab instead of sliding; the hover pill now
26
- * always returns to the selected tab as it fades.
27
- */
28
-
29
- import { Tabs } from '@base-ui/react/tabs'
30
- import { AnimatePresence, motion } from 'motion/react'
31
- import {
32
- Children,
33
- createContext,
34
- type ForwardRefExoticComponent,
35
- forwardRef,
36
- type HTMLAttributes,
37
- isValidElement,
38
- type ReactNode,
39
- type RefAttributes,
40
- useCallback,
41
- useContext,
42
- useEffect,
43
- useId,
44
- useRef,
45
- useState,
46
- } from 'react'
47
- import { GooIndicator } from '../../../lib/goo-indicator'
48
- import type { IconComponent } from '../../../lib/icon-context'
49
- import { useShape } from '../../../lib/shape-context'
50
- import { type SizeVariant, useSize } from '../../../lib/size-context'
51
- import { spring } from '../../../lib/springs'
52
- import { useControllableState } from '../../../lib/use-controllable-state'
53
- import { useFluidHover } from '../../../lib/use-fluid-hover'
54
- import { cn } from '../../../lib/utils'
55
- import { SizeProvider } from '../../../primitives/sizes'
56
-
57
- interface TabsSubtleContextValue {
58
- registerTab: (index: number, element: HTMLElement | null) => void
59
- hoveredIndex: number | null
60
- selectedIndex: number
61
- idPrefix: string | undefined
62
- activeLabel: boolean
63
- }
64
-
65
- const TabsSubtleContext = createContext<TabsSubtleContextValue | null>(null)
66
-
67
- const isPanel = (child: ReactNode) => isValidElement(child) && child.type === TabsSubtlePanel
68
-
69
- function useTabsSubtle() {
70
- const ctx = useContext(TabsSubtleContext)
71
- if (!ctx) throw new Error('useTabsSubtle must be used within a TabsSubtle')
72
- return ctx
73
- }
74
-
75
- interface TabsSubtleProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onSelect'> {
76
- /** TabsSubtle.Item children, and optionally the TabsSubtle.Panel children they select. */
77
- children: ReactNode
78
- /** Index of the currently selected tab. Controlled — pair it with `onSelect`. */
79
- selectedIndex?: number
80
- /** Selected tab on first render when uncontrolled. Defaults to `0`. */
81
- defaultSelectedIndex?: number
82
- /** Called when a tab is selected. */
83
- onSelect?: (index: number) => void
84
- /** Prefix for ARIA IDs linking tabs to panels. Defaults to a generated one when panels are nested inside. */
85
- idPrefix?: string
86
- /** When true, only the selected tab shows its text label. Requires icons on tabs. Defaults to `false`. */
87
- activeLabel?: boolean
88
- /** Pins the tabs to one step of the size ladder (default 36px, compact 28px). Defaults to the surrounding SizeProvider. */
89
- size?: SizeVariant
90
- }
91
-
92
- type TabsSubtleComponent = ForwardRefExoticComponent<TabsSubtleProps & RefAttributes<HTMLDivElement>> & {
93
- Item: typeof TabsSubtleItem
94
- Panel: typeof TabsSubtlePanel
95
- }
96
-
97
- /**
98
- * Tab navigation with smooth pill animations.
99
- *
100
- * A borderless tab strip: the selected pill melts from tab to tab like a drop
101
- * (the liquid indicators in Morph), a lighter hover pill previews the next one, and the active label animates to semibold
102
- * without shifting. With `activeLabel`, tabs collapse to their icon and the
103
- * selected one expands its label to a measured width. Base UI owns
104
- * `role="tablist"`, the roving tabindex and Arrow/Home/End navigation
105
- * (manual activation — arrows move, Enter or Space selects). Uncontrolled with
106
- * `defaultSelectedIndex`, or controlled with `selectedIndex` + `onSelect`.
107
- *
108
- * The root element is the tab list itself, so nested `TabsSubtle.Panel`
109
- * children are lifted out and rendered as its siblings, wired to the tabs
110
- * through a generated id prefix; panels rendered outside still take
111
- * `selectedIndex` and `idPrefix` as props.
112
- *
113
- * Statics:
114
- * - `TabsSubtle.Item` — one tab: `index`, `label`, optional `icon`.
115
- * - `TabsSubtle.Panel` — content for the tab with the same `index`.
116
- *
117
- * @example {@include ./examples.mdx}
118
- */
119
- const TabsSubtle = forwardRef<HTMLDivElement, TabsSubtleProps>(
120
- (
121
- {
122
- children,
123
- selectedIndex: selectedIndexProp,
124
- defaultSelectedIndex = 0,
125
- onSelect: onSelectProp,
126
- idPrefix,
127
- activeLabel = false,
128
- size,
129
- className,
130
- ...props
131
- },
132
- ref,
133
- ) => {
134
- const [selectedIndex, onSelect] = useControllableState(selectedIndexProp, defaultSelectedIndex, onSelectProp)
135
-
136
- // the root IS the tab list, so panels written inside it are rendered right after it
137
- const childList = Children.toArray(children)
138
- const panels = childList.filter(isPanel)
139
- const tabs = childList.filter(child => !isPanel(child))
140
- const generatedIdPrefix = useId()
141
- const resolvedIdPrefix = idPrefix ?? (panels.length > 0 ? generatedIdPrefix : undefined)
142
-
143
- const containerRef = useRef<HTMLDivElement>(null)
144
- const isMouseInside = useRef(false)
145
- const shape = useShape()
146
-
147
- const {
148
- activeIndex: hoveredIndex,
149
- setActiveIndex: setHoveredIndex,
150
- itemRects: tabRects,
151
- handlers,
152
- registerItem,
153
- measureItems: measureTabs,
154
- } = useFluidHover(containerRef, { axis: 'x' })
155
-
156
- // Track tab elements locally so we can observe their individual resizes
157
- const tabElementsRef = useRef(new Map<number, HTMLElement>())
158
- const registerTab = useCallback(
159
- (index: number, element: HTMLElement | null) => {
160
- registerItem(index, element)
161
- if (element) {
162
- tabElementsRef.current.set(index, element)
163
- } else {
164
- tabElementsRef.current.delete(index)
165
- }
166
- },
167
- [registerItem],
168
- )
169
-
170
- useEffect(() => {
171
- measureTabs()
172
- }, [measureTabs, children])
173
-
174
- // Observe individual tab buttons for resize (label expand/collapse in activeLabel mode)
175
- useEffect(() => {
176
- const elements = tabElementsRef.current
177
- if (elements.size === 0) return
178
- const ro = new ResizeObserver(() => measureTabs())
179
- elements.forEach(el => ro.observe(el))
180
- return () => ro.disconnect()
181
- }, [measureTabs, children])
182
-
183
- // Wrap handlers to track isMouseInside
184
- const handleMouseMove = useCallback(
185
- (e: React.MouseEvent) => {
186
- isMouseInside.current = true
187
- handlers.onMouseMove(e)
188
- },
189
- [handlers],
190
- )
191
-
192
- const handleMouseLeave = useCallback(() => {
193
- isMouseInside.current = false
194
- handlers.onMouseLeave()
195
- }, [handlers])
196
-
197
- const [focusedIndex, setFocusedIndex] = useState<number | null>(null)
198
-
199
- const selectedRect = tabRects[selectedIndex]
200
- const hoverRect = hoveredIndex !== null ? tabRects[hoveredIndex] : null
201
- const focusRect = focusedIndex !== null ? tabRects[focusedIndex] : null
202
- const isHoveringSelected = hoveredIndex === selectedIndex
203
- const isHovering = hoveredIndex !== null && !isHoveringSelected
204
-
205
- const root = (
206
- <TabsSubtleContext.Provider
207
- value={{
208
- registerTab,
209
- hoveredIndex,
210
- selectedIndex,
211
- idPrefix: resolvedIdPrefix,
212
- activeLabel,
213
- }}
214
- >
215
- {/* Root is merged into List via `render` so a single <div> is emitted,
216
- matching the previous DOM structure. Base UI owns role="tablist",
217
- roving tabindex, and Arrow/Home/End keyboard navigation.
218
- `activateOnFocus={false}` keeps manual activation: arrows move
219
- focus, Enter/Space selects. */}
220
- <Tabs.Root
221
- value={selectedIndex}
222
- onValueChange={value => {
223
- if (typeof value === 'number') onSelect(value)
224
- }}
225
- render={
226
- <Tabs.List
227
- activateOnFocus={false}
228
- ref={(node: HTMLDivElement | null) => {
229
- // React 18 types: `useRef<T>(null)` is a read-only RefObject.
230
- ;(containerRef as React.MutableRefObject<HTMLDivElement | null>).current = node
231
- if (typeof ref === 'function') ref(node)
232
- else if (ref) (ref as React.MutableRefObject<HTMLDivElement | null>).current = node
233
- }}
234
- onMouseMove={handleMouseMove}
235
- onMouseLeave={handleMouseLeave}
236
- onFocus={(e: React.FocusEvent<HTMLDivElement>) => {
237
- const indexAttr = (e.target as HTMLElement)
238
- .closest('[data-fluid-hover-index]')
239
- ?.getAttribute('data-fluid-hover-index')
240
- if (indexAttr != null) {
241
- const idx = Number(indexAttr)
242
- setHoveredIndex(idx)
243
- setFocusedIndex((e.target as HTMLElement).matches(':focus-visible') ? idx : null)
244
- }
245
- }}
246
- onBlur={(e: React.FocusEvent<HTMLDivElement>) => {
247
- if (containerRef.current?.contains(e.relatedTarget as Node)) return
248
- setFocusedIndex(null)
249
- if (isMouseInside.current) return
250
- setHoveredIndex(null)
251
- }}
252
- className={cn(
253
- // -mx-1 px-1 / -my-1 py-1 give the 2px-outset focus ring room
254
- // to draw without being clipped by overflow-x-auto. The
255
- // max-width allows for the negative margins: fit-content
256
- // parents size against the margin box (8px narrower than the
257
- // border box), so a plain max-w-full would clamp the list 8px
258
- // too small and clip the first/last tab's ring.
259
- 'relative flex items-center select-none overflow-x-auto max-w-[calc(100%_+_8px)] scrollbar-hide -mx-1 px-1 -my-1 py-1',
260
- className,
261
- )}
262
- {...props}
263
- >
264
- {selectedRect && (
265
- <GooIndicator
266
- rect={selectedRect}
267
- className={cn('bg-active', shape.bg)}
268
- opacity={isHovering ? 0.8 : 1}
269
- />
270
- )}
271
-
272
- {/* the hover pill rests on the selected tab, so it drips back into it as it fades */}
273
- {selectedRect && (
274
- <GooIndicator
275
- rect={isHovering && hoverRect ? hoverRect : selectedRect}
276
- className={cn('bg-active', shape.bg)}
277
- transition={spring.fast}
278
- opacity={isHovering ? 0.4 : 0}
279
- />
280
- )}
281
-
282
- {/* Focus ring */}
283
- <AnimatePresence>
284
- {focusRect && (
285
- <motion.div
286
- className={cn('absolute pointer-events-none z-20 border border-focus-ring', shape.focusRing)}
287
- initial={false}
288
- animate={{
289
- left: focusRect.left - 2,
290
- top: focusRect.top - 2,
291
- width: focusRect.width + 4,
292
- height: focusRect.height + 4,
293
- }}
294
- exit={{ opacity: 0, transition: spring.fast.exit }}
295
- transition={{
296
- ...spring.fast,
297
- opacity: { duration: spring.fast.duration },
298
- }}
299
- />
300
- )}
301
- </AnimatePresence>
302
-
303
- {tabs}
304
- </Tabs.List>
305
- }
306
- />
307
- {panels}
308
- </TabsSubtleContext.Provider>
309
- )
310
-
311
- // A size prop pins every tab to one ladder step.
312
- return size ? <SizeProvider size={size}>{root}</SizeProvider> : root
313
- },
314
- ) as TabsSubtleComponent
315
-
316
- TabsSubtle.displayName = 'TabsSubtle'
317
-
318
- interface TabsSubtleItemProps extends HTMLAttributes<HTMLButtonElement> {
319
- /** Icon displayed in the tab. */
320
- icon?: IconComponent
321
- /** Text label for the tab. */
322
- label: string
323
- /** Position index within the tab list. */
324
- index: number
325
- }
326
-
327
- const TabsSubtleItem = forwardRef<HTMLButtonElement, TabsSubtleItemProps>(
328
- ({ icon: Icon, label, index, className, ...props }, ref) => {
329
- const internalRef = useRef<HTMLButtonElement | null>(null)
330
- // The collapsing label animates to a MEASURED layout width, not "auto":
331
- // framer resolves an "auto" target from the element's *visual*
332
- // (transformed) size, so under a scaled ancestor (e.g. /demo's card) the
333
- // spring overshoots to scale-x the real width and snaps when "auto"
334
- // lands. offsetWidth and ResizeObserver are transform-immune — same
335
- // setup as the accordions' height animation.
336
- const [labelWidth, setLabelWidth] = useState<number | null>(null)
337
- const labelRoRef = useRef<ResizeObserver | null>(null)
338
- const measureLabel = useCallback((el: HTMLSpanElement | null) => {
339
- labelRoRef.current?.disconnect()
340
- labelRoRef.current = null
341
- if (!el) return
342
- const update = () => setLabelWidth(el.offsetWidth)
343
- update()
344
- labelRoRef.current = new ResizeObserver(update)
345
- labelRoRef.current.observe(el)
346
- }, [])
347
- const shape = useShape()
348
- const sizeClasses = useSize()
349
- const { registerTab, hoveredIndex, selectedIndex, idPrefix, activeLabel } = useTabsSubtle()
350
-
351
- useEffect(() => {
352
- registerTab(index, internalRef.current)
353
- return () => registerTab(index, null)
354
- }, [index, registerTab])
355
-
356
- const isSelected = selectedIndex === index
357
- const isActive = hoveredIndex === index || isSelected
358
- const collapseLabel = activeLabel && !!Icon
359
- const showLabel = !collapseLabel || isSelected
360
-
361
- const labelContent = (
362
- // Both stacked spans carry the text-box trim so the invisible bold
363
- // sizer and the visible label keep identical boxes.
364
- <span ref={measureLabel} className={cn('inline-grid whitespace-nowrap', sizeClasses.text)}>
365
- <span
366
- className="col-start-1 row-start-1 invisible [text-box:trim-both_cap_alphabetic] weight-semibold"
367
- aria-hidden="true"
368
- >
369
- {label}
370
- </span>
371
- <span
372
- className={cn(
373
- 'col-start-1 row-start-1 transition-[color,font-variation-settings] duration-fast [text-box:trim-both_cap_alphabetic]',
374
- isActive ? 'text-foreground' : 'text-muted-foreground',
375
- isSelected ? 'weight-semibold' : 'weight-normal',
376
- )}
377
- >
378
- {label}
379
- </span>
380
- </span>
381
- )
382
-
383
- return (
384
- // Base UI Tab renders a native <button type="button"> and wires
385
- // role="tab", aria-selected, roving tabindex, and activation for us.
386
- // id/aria-controls are only overridden when an idPrefix is supplied so
387
- // externally rendered TabsSubtlePanel elements stay linked.
388
- <Tabs.Tab
389
- ref={(node: HTMLElement | null) => {
390
- const button = node as HTMLButtonElement | null
391
- internalRef.current = button
392
- if (typeof ref === 'function') ref(button)
393
- else if (ref) (ref as React.MutableRefObject<HTMLButtonElement | null>).current = button
394
- }}
395
- value={index}
396
- data-fluid-hover-index={index}
397
- id={idPrefix ? `${idPrefix}-tab-${index}` : undefined}
398
- aria-controls={idPrefix ? `${idPrefix}-panel-${index}` : undefined}
399
- aria-label={collapseLabel && !showLabel ? label : undefined}
400
- className={cn(
401
- // Fixed heights (was py-2 around a 19.5px line box ≈ 35.5px) so the
402
- // text-box trim on the label doesn't shrink the tab. Standalone
403
- // pills sit directly on the ladder's control height.
404
- 'relative z-10 flex items-center cursor-pointer bg-transparent border-none outline-none',
405
- sizeClasses.control,
406
- sizeClasses.px,
407
- !collapseLabel && sizeClasses.gap,
408
- shape.bg,
409
- className,
410
- )}
411
- {...props}
412
- >
413
- {Icon && (
414
- <Icon
415
- size={sizeClasses.icon}
416
- strokeWidth={isActive ? 2 : 1.5}
417
- className={cn(
418
- 'shrink-0 transition-[color,stroke-width] duration-fast',
419
- isActive ? 'text-foreground' : 'text-muted-foreground',
420
- )}
421
- />
422
- )}
423
- {collapseLabel ? (
424
- <AnimatePresence initial={false}>
425
- {showLabel && (
426
- <motion.span
427
- key="label"
428
- className="overflow-hidden"
429
- // Until the measurement lands, let CSS resolve the width
430
- // instead of handing framer "auto": framer resolves an "auto"
431
- // target from the element's *visual* size, so under a scaled
432
- // ancestor (the /demo card, ~1.76x) it writes back a layout
433
- // width that much too wide, then springs back down when the
434
- // measured value arrives — the selected tab visibly pulses on
435
- // arrival. Plain CSS auto is the true layout width, and the
436
- // measured number that follows matches it exactly.
437
- style={labelWidth == null ? { width: 'auto' } : undefined}
438
- initial={{ width: 0, opacity: 0, marginLeft: 0 }}
439
- animate={{
440
- ...(labelWidth != null ? { width: labelWidth } : null),
441
- opacity: 1,
442
- // Matches the ladder's icon-to-label gap (gap-2 / gap-1.5).
443
- marginLeft: sizeClasses.variant === 'compact' ? 6 : 8,
444
- }}
445
- exit={{ width: 0, opacity: 0, marginLeft: 0 }}
446
- transition={{
447
- ...spring.fast,
448
- opacity: { duration: spring.fast.exit.duration },
449
- }}
450
- >
451
- {labelContent}
452
- </motion.span>
453
- )}
454
- </AnimatePresence>
455
- ) : (
456
- labelContent
457
- )}
458
- </Tabs.Tab>
459
- )
460
- },
461
- )
462
-
463
- TabsSubtleItem.displayName = 'TabsSubtleItem'
464
-
465
- interface TabsSubtlePanelProps extends HTMLAttributes<HTMLDivElement> {
466
- /** Index of this panel; rendered only when it matches the selected tab. */
467
- index: number
468
- /** Currently selected tab index. Defaults to the enclosing TabsSubtle's selection. */
469
- selectedIndex?: number
470
- /** Must match the TabsSubtle idPrefix. Defaults to the enclosing TabsSubtle's prefix. */
471
- idPrefix?: string
472
- /** Panel content, only rendered when selected. */
473
- children: ReactNode
474
- }
475
-
476
- // Written either inside <TabsSubtle> (the root lifts it out of the tab list
477
- // and it reads the selection from context) or outside it, next to the tabs
478
- // (then it takes `selectedIndex` and `idPrefix` as props, as upstream). Either
479
- // way it cannot use Base UI's Tabs.Panel — which needs the Tabs.Root context,
480
- // and that root is merged into the tab list — so it stays a plain tabpanel
481
- // linked to its tab through the shared idPrefix.
482
- const TabsSubtlePanel = forwardRef<HTMLDivElement, TabsSubtlePanelProps>(
483
- ({ index, selectedIndex, idPrefix, children, className, ...props }, ref) => {
484
- const ctx = useContext(TabsSubtleContext)
485
- const resolvedSelectedIndex = selectedIndex ?? ctx?.selectedIndex ?? -1
486
- const resolvedIdPrefix = idPrefix ?? ctx?.idPrefix
487
- const isSelected = resolvedSelectedIndex === index
488
-
489
- return (
490
- <div
491
- ref={ref}
492
- id={resolvedIdPrefix ? `${resolvedIdPrefix}-panel-${index}` : undefined}
493
- role="tabpanel"
494
- aria-labelledby={resolvedIdPrefix ? `${resolvedIdPrefix}-tab-${index}` : undefined}
495
- hidden={!isSelected}
496
- tabIndex={-1}
497
- className={cn('outline-none', className)}
498
- {...props}
499
- >
500
- {isSelected && children}
501
- </div>
502
- )
503
- },
504
- )
505
-
506
- TabsSubtlePanel.displayName = 'TabsSubtlePanel'
507
-
508
- Object.assign(TabsSubtle, { Item: TabsSubtleItem, Panel: TabsSubtlePanel })
509
-
510
- export type { TabsSubtleItemProps, TabsSubtlePanelProps, TabsSubtleProps }
511
- export { TabsSubtle, TabsSubtleItem, TabsSubtlePanel }
512
- export default TabsSubtle
@@ -1,123 +0,0 @@
1
- import AlertDialog from './index'
2
- import Button from '../../button'
3
- import Toast, { toast } from '../toast'
4
- import Dialog from '../dialog'
5
- import Tooltip from '../tooltip'
6
- import PendingDemo from './pending-demo'
7
-
8
- # Confirm a destructive step
9
-
10
- A press outside does nothing; the answer is Cancel, Delete or Escape.
11
-
12
- <AlertDialog>
13
- <AlertDialog.Trigger render={<Button variant="secondary">Delete project</Button>} />
14
- <AlertDialog.Content>
15
- <AlertDialog.Header>
16
- <AlertDialog.Title>Delete this project?</AlertDialog.Title>
17
- <AlertDialog.Description>Its pages and history go with it. This can't be undone.</AlertDialog.Description>
18
- </AlertDialog.Header>
19
- <AlertDialog.Footer>
20
- <AlertDialog.Close render={<Button variant="ghost">Cancel</Button>} />
21
- <AlertDialog.Close render={<Button>Delete</Button>} />
22
- </AlertDialog.Footer>
23
- </AlertDialog.Content>
24
- </AlertDialog>
25
-
26
- # Wait for the confirm
27
-
28
- `AlertDialog.Action`'s `onClick` returns a promise: the button folds into a spinner, Cancel greys out and Escape does nothing until it settles, then the dialog closes.
29
-
30
- <AlertDialog>
31
- <AlertDialog.Trigger render={<Button variant="secondary">Archive workspace</Button>} />
32
- <AlertDialog.Content>
33
- <AlertDialog.Header>
34
- <AlertDialog.Title>Archive this workspace?</AlertDialog.Title>
35
- <AlertDialog.Description>Members lose access until it is restored.</AlertDialog.Description>
36
- </AlertDialog.Header>
37
- <AlertDialog.Footer>
38
- <AlertDialog.Cancel>Cancel</AlertDialog.Cancel>
39
- <AlertDialog.Action onClick={() => new Promise(resolve => setTimeout(resolve, 1600))}>Archive</AlertDialog.Action>
40
- </AlertDialog.Footer>
41
- </AlertDialog.Content>
42
- </AlertDialog>
43
-
44
- # With a mutation's pending
45
-
46
- `pending` takes a mutation's `isPending`. A plain `onClick={() => mutate()}` then keeps the dialog open and locked while it runs, and closes it once `pending` falls back to false.
47
-
48
- <PendingDemo />
49
-
50
- # When it fails
51
-
52
- A rejected promise keeps the dialog open and hands the reason to `onError` — here a toast — so the person can try again or cancel.
53
-
54
- <Toast manager={toast} position="bottom-right">
55
- <AlertDialog>
56
- <AlertDialog.Trigger render={<Button variant="secondary">Delete account</Button>} />
57
- <AlertDialog.Content>
58
- <AlertDialog.Header>
59
- <AlertDialog.Title>Delete your account?</AlertDialog.Title>
60
- <AlertDialog.Description>Everything you made goes with it.</AlertDialog.Description>
61
- </AlertDialog.Header>
62
- <AlertDialog.Footer>
63
- <AlertDialog.Cancel>Keep it</AlertDialog.Cancel>
64
- <AlertDialog.Action
65
- variant="destructive"
66
- onClick={() => new Promise((resolve, reject) => setTimeout(() => reject(new Error('The server is busy')), 1400))}
67
- onError={error => toast.error({ title: 'Could not delete', description: error.message })}
68
- >
69
- Delete
70
- </AlertDialog.Action>
71
- </AlertDialog.Footer>
72
- </AlertDialog.Content>
73
- </AlertDialog>
74
- </Toast>
75
-
76
- # From the pointer
77
-
78
- The same morph options as Dialog: here a circle grows from where you pressed.
79
-
80
- <AlertDialog>
81
- <AlertDialog.Trigger render={<Button variant="secondary">Sign out</Button>} />
82
- <AlertDialog.Content from="pointer" effect="morph">
83
- <AlertDialog.Header>
84
- <AlertDialog.Title>Sign out?</AlertDialog.Title>
85
- <AlertDialog.Description>You'll need to sign in again on this device.</AlertDialog.Description>
86
- </AlertDialog.Header>
87
- <AlertDialog.Footer>
88
- <AlertDialog.Close render={<Button variant="ghost">Stay</Button>} />
89
- <AlertDialog.Close render={<Button>Sign out</Button>} />
90
- </AlertDialog.Footer>
91
- </AlertDialog.Content>
92
- </AlertDialog>
93
-
94
- # Inside a dialog
95
-
96
- Opened from a dialog, the alert lifts above it, and so does the tooltip on the button that opens it.
97
-
98
- <Dialog>
99
- <Dialog.Trigger render={<Button variant="secondary">Project settings</Button>} />
100
- <Dialog.Content>
101
- <Dialog.Header>
102
- <Dialog.Title>Project settings</Dialog.Title>
103
- <Dialog.Description>Rename, transfer or delete this project.</Dialog.Description>
104
- </Dialog.Header>
105
- <Dialog.Footer>
106
- <AlertDialog>
107
- <Tooltip content="Removes it for everyone">
108
- <AlertDialog.Trigger render={<Button variant="destructive">Delete project</Button>} />
109
- </Tooltip>
110
- <AlertDialog.Content>
111
- <AlertDialog.Header>
112
- <AlertDialog.Title>Delete this project?</AlertDialog.Title>
113
- <AlertDialog.Description>Its pages and history go with it.</AlertDialog.Description>
114
- </AlertDialog.Header>
115
- <AlertDialog.Footer>
116
- <AlertDialog.Cancel>Cancel</AlertDialog.Cancel>
117
- <AlertDialog.Action variant="destructive" onClick={() => new Promise(resolve => setTimeout(resolve, 1200))}>Delete</AlertDialog.Action>
118
- </AlertDialog.Footer>
119
- </AlertDialog.Content>
120
- </AlertDialog>
121
- </Dialog.Footer>
122
- </Dialog.Content>
123
- </Dialog>