@justanarthur/modo-ui 0.6.0-canary.9 → 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-c7rwx0ap.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-c74gf16d.js → components-1z6tdadk.js} +24 -40
  91. package/dist/shared/{components-bae8sbjx.js → components-27nnvrwe.js} +14 -15
  92. package/dist/shared/{components-qh1cvj6p.js → components-2dxkv6zm.js} +7 -8
  93. package/dist/shared/{components-y0kfy2g4.js → components-2ecg8svx.js} +152 -234
  94. package/dist/shared/{components-c5w5zk0s.js → components-2ph6t61s.js} +34 -37
  95. package/dist/shared/{components-4j3t39dd.js → components-39jq9va1.js} +24 -29
  96. package/dist/shared/components-3ky44908.js +9 -0
  97. package/dist/shared/{components-syynwm1r.js → components-3mkepka5.js} +25 -28
  98. package/dist/shared/{components-wgtjt2af.js → components-4700p9kz.js} +22 -24
  99. package/dist/shared/{components-yhgq0qxx.js → components-59efxjd9.js} +12 -13
  100. package/dist/shared/{components-91zw3d9f.js → components-5vgpnxgy.js} +27 -51
  101. package/dist/shared/{components-kz5q11pp.js → components-5xc2j8jz.js} +18 -19
  102. package/dist/shared/{components-zkk3fmw8.js → components-6p8tfcd6.js} +29 -57
  103. package/dist/shared/{components-4nck8acq.js → components-7r3etddy.js} +54 -19
  104. package/dist/shared/{components-svkt577j.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-pv1dyrtn.js → components-b3c5et5b.js} +38 -49
  108. package/dist/shared/{components-rrbpmfx4.js → components-c6s6b43g.js} +2 -3
  109. package/dist/shared/{components-pwayrkw9.js → components-chacnk61.js} +19 -19
  110. package/dist/shared/{components-71nbt03m.js → components-cv16mryv.js} +7 -26
  111. package/dist/shared/{components-hgv6tygd.js → components-d6xtjht3.js} +30 -35
  112. package/dist/shared/{components-z8fedth5.js → components-dk0gjr5a.js} +18 -19
  113. package/dist/shared/{components-cet3jpa0.js → components-fzrq6tr3.js} +34 -37
  114. package/dist/shared/{components-cnead5qm.js → components-gc5vtq2f.js} +30 -66
  115. package/dist/shared/components-gf5s6ap9.js +42 -0
  116. package/dist/shared/{components-0h78g3b5.js → components-gz8zf3ec.js} +55 -56
  117. package/dist/shared/{components-mattt5jp.js → components-h2ajmhwn.js} +35 -107
  118. package/dist/shared/{components-m06yq8wk.js → components-hqeq3w9q.js} +23 -38
  119. package/dist/shared/{components-7qx17na9.js → components-hw9yk32z.js} +24 -36
  120. package/dist/shared/components-hyq23phv.js +310 -0
  121. package/dist/shared/{components-9jmjnkqd.js → components-jbbmdr74.js} +22 -41
  122. package/dist/shared/{components-dcc02hs2.js → components-jjw69c4c.js} +4 -7
  123. package/dist/shared/{components-303jf96s.js → components-jthe1pwb.js} +420 -139
  124. package/dist/shared/{components-dtca4s6b.js → components-jwst3vtj.js} +76 -224
  125. package/dist/shared/{components-dc5q749x.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-qx27excf.js → components-mjthm1kf.js} +9 -13
  129. package/dist/shared/{components-1e64t8aj.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-w2jqa6hx.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-2a7hcand.js → components-rr7a6ja9.js} +27 -59
  136. package/dist/shared/{components-005jt2nz.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-p0fm0bab.js → components-w1r67ag9.js} +149 -294
  144. package/dist/shared/{components-xd3emmy4.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-yxmxn2jp.js → components-y9y0g8er.js} +28 -52
  148. package/dist/shared/components-ypp01w3p.js +986 -0
  149. package/dist/shared/{components-czdvj1a8.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-01w9qcfa.js +0 -277
  385. package/dist/shared/components-124epb7f.js +0 -53
  386. package/dist/shared/components-26snnbs9.js +0 -322
  387. package/dist/shared/components-2krsc300.js +0 -254
  388. package/dist/shared/components-2qbqqpgq.js +0 -1545
  389. package/dist/shared/components-34txk9rj.js +0 -35
  390. package/dist/shared/components-3h92d94m.js +0 -23
  391. package/dist/shared/components-4vfm04wq.js +0 -82
  392. package/dist/shared/components-54nq988h.js +0 -123
  393. package/dist/shared/components-7s7pykk5.js +0 -281
  394. package/dist/shared/components-868v7scv.js +0 -399
  395. package/dist/shared/components-8jrk5eye.js +0 -448
  396. package/dist/shared/components-adkarj8n.js +0 -35
  397. package/dist/shared/components-b1e239g3.js +0 -28
  398. package/dist/shared/components-b94t6qtj.js +0 -143
  399. package/dist/shared/components-bsqynhaj.js +0 -179
  400. package/dist/shared/components-c9yr4ed1.js +0 -44
  401. package/dist/shared/components-d3shbwqq.js +0 -95
  402. package/dist/shared/components-dhgk6mbt.js +0 -16
  403. package/dist/shared/components-drxrtnp2.js +0 -25
  404. package/dist/shared/components-f7h57m6t.js +0 -59
  405. package/dist/shared/components-g3eafs70.js +0 -337
  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-mhza2wdn.js +0 -482
  414. package/dist/shared/components-mrbaxt8q.js +0 -62
  415. package/dist/shared/components-pt5ftm4p.js +0 -38
  416. package/dist/shared/components-rtadhd9j.js +0 -64
  417. package/dist/shared/components-tv7b8tet.js +0 -271
  418. package/dist/shared/components-tz4gaf1v.js +0 -23
  419. package/dist/shared/components-wbbckbw8.js +0 -34
  420. package/dist/shared/components-wknae3m4.js +0 -298
  421. package/dist/shared/components-xdqmt6ed.js +0 -20
  422. package/dist/shared/components-xjkdvnbg.js +0 -107
  423. package/dist/shared/components-z3v0n0de.js +0 -11
  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 -575
  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,96 +0,0 @@
1
- import Switch from './index'
2
- import { Label } from '../input'
3
-
4
- # Basics
5
-
6
- ## Basic
7
-
8
- A labelled switch. Uncontrolled here — it keeps its own state; pass
9
- `checked` and `onToggle` to control it.
10
-
11
- <Switch label="Notifications" />
12
-
13
- ## Description
14
-
15
- `description` adds a muted line under the label, and `trackSide="end"` pushes the track to the far edge, as in a settings row.
16
-
17
- <Switch
18
- className="w-80 max-w-full"
19
- trackSide="end"
20
- label="Auto-update"
21
- description="Install updates in the background and restart when idle"
22
- />
23
-
24
- ## Bare
25
-
26
- Without a `label` the switch is the track alone: point a `<label htmlFor>` at its `id`, or name it with `aria-label`. The thumb still drags.
27
-
28
- <div className="flex flex-col gap-3">
29
- <div className="flex items-center gap-3">
30
- <Switch id="bare-wifi" defaultChecked />
31
- <Label htmlFor="bare-wifi">Wi-Fi</Label>
32
- </div>
33
- <div className="flex items-center gap-4">
34
- <Switch aria-label="Airplane mode" />
35
- <Switch aria-label="Bluetooth" size="compact" defaultChecked />
36
- <Switch aria-label="Hotspot" disabled />
37
- </div>
38
- </div>
39
-
40
- ## Compact
41
-
42
- `size="compact"` shrinks the track, thumb and label one step down the
43
- size ladder. `defaultChecked` starts it on.
44
-
45
- <div className="flex flex-col">
46
- <Switch size="compact" label="Auto-save" defaultChecked />
47
- <Switch size="compact" label="Show hidden files" />
48
- </div>
49
-
50
- ## Disabled
51
-
52
- `disabled` dims the row and ignores pointer and keyboard input.
53
-
54
- <Switch label="Disabled option" disabled />
55
-
56
- # Group
57
-
58
- `Switch.Group` frames switches as a settings list: each one becomes a row with its track at the far edge. Here beside a label column, as on a settings page; on a narrow page the label stacks above it.
59
-
60
- <div className="@container w-full max-w-3xl">
61
- <div className="grid gap-3 @xl:grid-cols-[10rem_1fr] @xl:gap-6">
62
- <p id="automation" className="text-body weight-medium text-foreground [text-box:trim-both_cap_alphabetic] @xl:pt-4">
63
- Automation
64
- </p>
65
- <Switch.Group aria-labelledby="automation">
66
- <Switch
67
- label="Remove Task OUT with old contracts"
68
- description="When an old contract is removed automatically, its Task OUT is removed too"
69
- />
70
- <Switch
71
- label="Block billing until damage is inspected"
72
- description="A contract can't be marked as billed while a damage inspection is required"
73
- />
74
- </Switch.Group>
75
- </div>
76
- </div>
77
-
78
- ## Group states
79
-
80
- Every switch in a group keeps its own state; a disabled row gets no highlight. Rows work without a description too.
81
-
82
- <Switch.Group aria-label="Notifications" className="w-96 max-w-full">
83
- <Switch label="Email" defaultChecked />
84
- <Switch label="Push notifications" />
85
- <Switch label="SMS" description="Not available in your region" disabled />
86
- </Switch.Group>
87
-
88
- ## Compact group
89
-
90
- `size` on the group pins every row to one step of the size ladder.
91
-
92
- <Switch.Group size="compact" aria-label="Editor" className="w-80 max-w-full">
93
- <Switch label="Auto-save" description="Save after every change" defaultChecked />
94
- <Switch label="Format on save" />
95
- <Switch label="Show hidden files" />
96
- </Switch.Group>
@@ -1,504 +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/switch.tsx` @ b3587bdbd83fc66c2a6aae3817ffb856cb09260b
5
- * MIT License © 2026 Micka Touillaud — fluidfunctionalism.com (notice: LICENSE.fluid-functionalism)
6
- * Local modifications:
7
- * - `"use client"` directive dropped (no RSC here).
8
- * - `framer-motion` → `motion/react`; `@/lib/*` imports rewritten to relative
9
- * `../../../lib/*` paths.
10
- * - Uncontrolled support (local addition, Base UI style): `checked` and
11
- * `onToggle` are optional; new `defaultChecked` seeds internal state and new
12
- * `onCheckedChange(checked)` reports every change, via the shared
13
- * `useControllableState`. With `checked` passed the component stays fully
14
- * controlled and `onToggle` fires exactly as upstream.
15
- * - Every in-body read of `checked` / `onToggle()` goes through the resolved
16
- * state (`isChecked`) and a `toggle()` that flips it and calls `onToggle`.
17
- * The Root's `onCheckedChange` is dropped: Base UI's keyboard and assistive
18
- * activation re-click its hidden input, which already reaches the row's
19
- * `onClick`, so keeping both toggled twice (a flip back, uncontrolled).
20
- * - `SwitchProps` members carry the FF docs API-table descriptions (plus the
21
- * new props), so modo's parser lists them.
22
- * - TSDoc with the FF docs page's examples added above the component;
23
- * `export default Switch` added.
24
- * - Styling reads DS tokens (AGENTS.md styling): the hex focus-ring
25
- * fallback → `ring-focus-ring` / `border-focus-ring`; literal colors →
26
- * color tokens; `duration-80|120|160` and tier-length JS durations →
27
- * `duration-<tier>` / `spring.*`.
28
- * - The thumb is a `GooIndicator` (`lib/goo-indicator.tsx`, local) inside
29
- * Base UI's Thumb: it stretches into a liquid drop as it travels. Its x is
30
- * React state while dragging (the indicator snaps to it) instead of a
31
- * motion value set per move.
32
- * - `description` (a muted line under the label, wired as
33
- * `aria-describedby`; the label then stays at full contrast and medium
34
- * weight) and `trackSide` (`"end"` pushes the track to the far edge) are
35
- * local additions, for settings rows.
36
- * - `Switch.Group` (local addition): switches as a settings list in one
37
- * outlined fieldset, after an outlined `Card.Group` (shared frame,
38
- * hairlines dropped around the fluid hover highlight). A switch inside
39
- * reads the group from context: track at the end, roomier padding, its
40
- * position from `lib/row-index.tsx`.
41
- * - Bare mode (local): `label` is optional and takes any node; without one
42
- * (outside a group) the switch is the track alone, Base UI's Switch.Root,
43
- * which then toggles itself (click, keyboard, a `<label htmlFor>` pointing
44
- * at its `id`) through `onCheckedChange`, with the thumb drag on the track
45
- * and a toggle that follows a drag swallowed. `name` / `value` /
46
- * `required` reach Base UI's hidden input in both modes.
47
- */
48
-
49
- import { Switch as SwitchPrimitive } from '@base-ui/react/switch'
50
- import type { Transition } from 'motion/react'
51
- import {
52
- Children,
53
- createContext,
54
- type ForwardRefExoticComponent,
55
- forwardRef,
56
- type HTMLAttributes,
57
- isValidElement,
58
- type ReactNode,
59
- type RefAttributes,
60
- useCallback,
61
- useContext,
62
- useId,
63
- useRef,
64
- useState,
65
- } from 'react'
66
- import { FluidHoverHighlight } from '../../../lib/fluid-hover-highlight'
67
- import { GooIndicator } from '../../../lib/goo-indicator'
68
- import { IndexedRows, useRowIndex } from '../../../lib/row-index'
69
- import { useShape } from '../../../lib/shape-context'
70
- import { type SizeVariant, useSize } from '../../../lib/size-context'
71
- import { spring } from '../../../lib/springs'
72
- import { useControllableState } from '../../../lib/use-controllable-state'
73
- import { useFluidHover, useRegisterFluidHoverItem } from '../../../lib/use-fluid-hover'
74
- import { cn } from '../../../lib/utils'
75
- import { SizeProvider } from '../../../primitives/sizes'
76
-
77
- interface SwitchProps extends HTMLAttributes<HTMLDivElement> {
78
- /** Label displayed next to the switch, any node. Omit it, outside a group, for the bare track (see Bare): name it with `aria-label`, `aria-labelledby` or a `<label htmlFor>` pointing at its `id`. */
79
- label?: ReactNode
80
- /** Secondary text under the label: what turning the switch on does. With one, the label stays at full contrast. */
81
- description?: ReactNode
82
- /** The side of the label the track sits on; `"end"` pushes it to the row's far edge, as in a settings list (always, inside a `Switch.Group`). Defaults to `"start"`. */
83
- trackSide?: 'start' | 'end'
84
- /** Whether the switch is on (controlled). Omit it to let the switch keep its own state, seeded from `defaultChecked`. */
85
- checked?: boolean
86
- /** Whether the switch starts on when uncontrolled. Defaults to `false`. */
87
- defaultChecked?: boolean
88
- /** Called when the switch is toggled. */
89
- onToggle?: () => void
90
- /** Called with the new state whenever the switch is toggled, controlled or not. */
91
- onCheckedChange?: (checked: boolean) => void
92
- /** Disables the switch. Defaults to `false`. */
93
- disabled?: boolean
94
- /** Form field name: a hidden checkbox input submits `value` while on. */
95
- name?: string
96
- /** Value submitted with `name` while on. Defaults to `"on"`. */
97
- value?: string
98
- /** Marks the hidden form input required. Defaults to `false`. */
99
- required?: boolean
100
- /** Transition for the thumb's slide and hover/press stretch. Defaults to the `spring.moderate` motion token. */
101
- thumbTransition?: Transition
102
- /** Pins the switch to one step of the size ladder (see Sizes). Defaults to the surrounding SizeProvider, else `"default"`. */
103
- size?: SizeVariant
104
- }
105
-
106
- interface SwitchGroupContextValue {
107
- registerItem: (index: number, element: HTMLElement | null) => void
108
- activeIndex: number | null
109
- count: number
110
- }
111
-
112
- const SwitchGroupContext = createContext<SwitchGroupContextValue | null>(null)
113
-
114
- type SwitchComponent = ForwardRefExoticComponent<SwitchProps & RefAttributes<HTMLDivElement>> & {
115
- Group: typeof SwitchGroup
116
- }
117
-
118
- // Track/thumb geometry per ladder step. The hover pill-extend and press
119
- // squash scale down with the thumb so the compact switch keeps the same feel.
120
- const METRICS = {
121
- default: {
122
- trackWidth: 34,
123
- trackHeight: 20,
124
- thumbSize: 16,
125
- pillExtend: 2,
126
- pressExtend: 4,
127
- pressShrink: 4,
128
- },
129
- compact: {
130
- trackWidth: 28,
131
- trackHeight: 16,
132
- thumbSize: 12,
133
- pillExtend: 2,
134
- pressExtend: 3,
135
- pressShrink: 3,
136
- },
137
- } as const
138
-
139
- const THUMB_OFFSET = 2
140
- const DRAG_DEAD_ZONE = 2
141
-
142
- /**
143
- * Toggle switch with animated thumb and label.
144
- *
145
- * The whole row — track and label — is the hit target: click anywhere to
146
- * toggle, or grab the thumb and drag it across the midpoint. The thumb
147
- * stretches into a pill on hover, squashes on press and melts across the
148
- * track like a drop when it toggles (see Morph), springing with the motion
149
- * tokens; a Base UI switch underneath carries the role, keyboard
150
- * toggling (Space/Enter) and focus ring. The label brightens when the switch
151
- * is on.
152
- *
153
- * Works controlled (`checked` + `onToggle`, exactly as upstream) or
154
- * uncontrolled (`defaultChecked`, with `onCheckedChange` reporting each
155
- * change). `size` pins it to one step of the size ladder; otherwise it
156
- * follows the surrounding SizeProvider. `description` adds a muted line under
157
- * the label and `trackSide="end"` moves the track to the row's far edge.
158
- *
159
- * Statics:
160
- * - `Switch.Group` — switches as a settings list in one outlined frame: each
161
- * `Switch` inside becomes a row with its track at the far edge, hairlines
162
- * divide the rows and a fluid hover highlight melts between them, dropping
163
- * the hairlines it touches (as in an outlined Card.Group); a disabled row
164
- * gets no highlight. Every switch keeps its own state. `size` pins every
165
- * row; name the group with `aria-label` or `aria-labelledby`.
166
- *
167
- * @example {@include ./examples.mdx}
168
- */
169
- const Switch = forwardRef<HTMLDivElement, SwitchProps>(
170
- (
171
- {
172
- label,
173
- description,
174
- trackSide = 'start',
175
- checked,
176
- defaultChecked = false,
177
- onToggle,
178
- onCheckedChange,
179
- disabled = false,
180
- name,
181
- value,
182
- required = false,
183
- thumbTransition,
184
- size,
185
- className,
186
- ...props
187
- },
188
- ref,
189
- ) => {
190
- const [isChecked, setChecked] = useControllableState(checked, defaultChecked, onCheckedChange)
191
- const toggle = useCallback(() => {
192
- setChecked(prev => !prev)
193
- onToggle?.()
194
- }, [setChecked, onToggle])
195
- const labelId = useId()
196
- const descriptionId = useId()
197
- const group = useContext(SwitchGroupContext)
198
- const index = useRowIndex()
199
- const rowRef = useRef<HTMLDivElement | null>(null)
200
- // A disabled row takes no clicks, so the group's highlight never lands on it.
201
- useRegisterFluidHoverItem(disabled ? undefined : group?.registerItem, index, rowRef)
202
- const end = trackSide === 'end' || !!group
203
- // In a group: a hairline toward the next row, dropped where it would cut the highlight.
204
- const divider = !!group && index < group.count - 1 && group.activeIndex !== index && group.activeIndex !== index + 1
205
- const [hovered, setHovered] = useState(false)
206
- const [pressed, setPressed] = useState(false)
207
- const sizeClasses = useSize(size)
208
- const m = METRICS[sizeClasses.variant]
209
- const thumbTravel = m.trackWidth - m.thumbSize - THUMB_OFFSET * 2
210
-
211
- const dragging = useRef(false)
212
- const didDrag = useRef(false)
213
- const pointerStart = useRef<{
214
- clientX: number
215
- originX: number
216
- } | null>(null)
217
- // Local: the dragged thumb's x, mirrored in a ref for the pointer handlers.
218
- const [dragX, setDragXState] = useState<number | null>(null)
219
- const dragXRef = useRef<number | null>(null)
220
- const setDragX = useCallback((x: number | null) => {
221
- dragXRef.current = x
222
- setDragXState(x)
223
- }, [])
224
-
225
- const thumbWidth = pressed ? m.thumbSize + m.pressExtend : hovered ? m.thumbSize + m.pillExtend : m.thumbSize
226
- const thumbHeight = pressed ? m.thumbSize - m.pressShrink : m.thumbSize
227
- const thumbY = pressed ? THUMB_OFFSET + m.pressShrink / 2 : THUMB_OFFSET
228
- const extraWidth = thumbWidth - m.thumbSize
229
- const thumbX = isChecked ? THUMB_OFFSET + thumbTravel - extraWidth : THUMB_OFFSET
230
- const thumb = { left: dragX ?? thumbX, top: thumbY, width: thumbWidth, height: thumbHeight }
231
-
232
- const handlePointerDown = useCallback(
233
- (e: React.PointerEvent<HTMLDivElement>) => {
234
- if (disabled) return
235
- if (e.pointerType === 'mouse' && e.button !== 0) return
236
- setPressed(true)
237
- dragging.current = false
238
- didDrag.current = false
239
- pointerStart.current = {
240
- clientX: e.clientX,
241
- // Where the pressed thumb rests.
242
- originX: isChecked ? THUMB_OFFSET + thumbTravel - m.pressExtend : THUMB_OFFSET,
243
- }
244
- ;(e.currentTarget as HTMLElement).setPointerCapture(e.pointerId)
245
- },
246
- [disabled, isChecked, thumbTravel, m],
247
- )
248
-
249
- const handlePointerMove = useCallback(
250
- (e: React.PointerEvent<HTMLDivElement>) => {
251
- if (!pointerStart.current) return
252
- const delta = e.clientX - pointerStart.current.clientX
253
-
254
- if (!dragging.current) {
255
- if (Math.abs(delta) < DRAG_DEAD_ZONE) return
256
- dragging.current = true
257
- }
258
-
259
- const dragMin = THUMB_OFFSET
260
- const pressedThumbWidth = m.thumbSize + m.pressExtend
261
- const dragMax = m.trackWidth - THUMB_OFFSET - pressedThumbWidth
262
- const rawX = pointerStart.current.originX + delta
263
- setDragX(Math.max(dragMin, Math.min(dragMax, rawX)))
264
- },
265
- [setDragX, m],
266
- )
267
-
268
- const handlePointerUp = useCallback(() => {
269
- if (!pointerStart.current) return
270
- setPressed(false)
271
-
272
- if (dragging.current) {
273
- didDrag.current = true
274
- dragging.current = false
275
-
276
- const currentX = dragXRef.current ?? pointerStart.current.originX
277
- const dragMin = THUMB_OFFSET
278
- const pressedThumbWidth = m.thumbSize + m.pressExtend
279
- const dragMax = m.trackWidth - THUMB_OFFSET - pressedThumbWidth
280
- const midpoint = (dragMin + dragMax) / 2
281
-
282
- const shouldBeOn = currentX > midpoint
283
-
284
- if (shouldBeOn !== isChecked) toggle()
285
- // Let go: the thumb springs from where it was dropped to its rest.
286
- setDragX(null)
287
-
288
- requestAnimationFrame(() => {
289
- didDrag.current = false
290
- })
291
- }
292
-
293
- pointerStart.current = null
294
- }, [isChecked, toggle, setDragX, m])
295
-
296
- const handlePointerCancel = useCallback(() => {
297
- if (!pointerStart.current) return
298
- setPressed(false)
299
-
300
- if (dragging.current) {
301
- dragging.current = false
302
- setDragX(null)
303
- }
304
-
305
- pointerStart.current = null
306
- }, [setDragX])
307
-
308
- const trackClass = cn(
309
- 'relative shrink-0 rounded-full outline-none cursor-pointer',
310
- 'transition-colors duration-fast',
311
- 'focus-visible:ring-1 focus-visible:ring-focus-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background',
312
- isChecked ? (hovered ? 'bg-brand-hover' : 'bg-brand') : hovered ? 'bg-accent-hover' : 'bg-accent',
313
- )
314
- const thumbElement = (
315
- <SwitchPrimitive.Thumb className="pointer-events-none absolute inset-0">
316
- <GooIndicator
317
- rect={thumb}
318
- className="rounded-full bg-thumb"
319
- shadow="shadow-thumb"
320
- transition={dragX === null ? (thumbTransition ?? spring.moderate) : false}
321
- />
322
- </SwitchPrimitive.Thumb>
323
- )
324
-
325
- // Bare: no label and no group — the track alone is the control, and Base
326
- // UI's own activation (click, keyboard, a label's htmlFor) toggles it.
327
- if (label === undefined && !group) {
328
- return (
329
- <SwitchPrimitive.Root
330
- ref={node => {
331
- rowRef.current = node as HTMLDivElement | null
332
- if (typeof ref === 'function') ref(node as HTMLDivElement | null)
333
- else if (ref) ref.current = node as HTMLDivElement | null
334
- }}
335
- checked={isChecked}
336
- onCheckedChange={() => {
337
- // The drag already toggled on release; its click must not toggle back.
338
- if (didDrag.current) return
339
- toggle()
340
- }}
341
- disabled={disabled}
342
- name={name}
343
- value={value}
344
- required={required}
345
- onPointerEnter={e => {
346
- if (e.pointerType === 'mouse') setHovered(true)
347
- }}
348
- onPointerLeave={() => setHovered(false)}
349
- onPointerDown={handlePointerDown}
350
- onPointerMove={handlePointerMove}
351
- onPointerUp={handlePointerUp}
352
- onPointerCancel={handlePointerCancel}
353
- className={cn(trackClass, 'touch-none', disabled && 'opacity-50 pointer-events-none', className)}
354
- style={{
355
- width: m.trackWidth,
356
- height: m.trackHeight,
357
- }}
358
- // The root's handlers are typed for Base UI's span.
359
- {...(props as HTMLAttributes<HTMLSpanElement>)}
360
- >
361
- {thumbElement}
362
- </SwitchPrimitive.Root>
363
- )
364
- }
365
-
366
- return (
367
- <div
368
- ref={node => {
369
- rowRef.current = node
370
- if (typeof ref === 'function') ref(node)
371
- else if (ref) ref.current = node
372
- }}
373
- className={cn(
374
- 'relative z-10 flex items-center cursor-pointer select-none touch-none',
375
- sizeClasses.gap,
376
- sizeClasses.px,
377
- sizeClasses.variant === 'compact' ? 'py-1' : 'py-2',
378
- group && (sizeClasses.variant === 'compact' ? 'px-3 py-2.5' : 'px-4 py-3.5'),
379
- disabled && 'opacity-50 pointer-events-none',
380
- className,
381
- )}
382
- onPointerEnter={e => {
383
- if (e.pointerType === 'mouse') setHovered(true)
384
- }}
385
- onPointerLeave={() => setHovered(false)}
386
- onPointerDown={handlePointerDown}
387
- onPointerMove={handlePointerMove}
388
- onPointerUp={handlePointerUp}
389
- onPointerCancel={handlePointerCancel}
390
- onClick={() => {
391
- if (disabled || didDrag.current) return
392
- toggle()
393
- }}
394
- {...props}
395
- >
396
- {/* Switch */}
397
- <SwitchPrimitive.Root
398
- checked={isChecked}
399
- aria-labelledby={label === undefined ? undefined : labelId}
400
- aria-describedby={description ? descriptionId : undefined}
401
- disabled={disabled}
402
- name={name}
403
- value={value}
404
- required={required}
405
- tabIndex={0}
406
- className={cn(trackClass, end && 'order-last')}
407
- style={{
408
- width: m.trackWidth,
409
- height: m.trackHeight,
410
- }}
411
- // Base UI re-dispatches this click on its hidden input, which bubbles to the row and toggles it: stop the original so a press toggles once.
412
- onClick={e => e.stopPropagation()}
413
- >
414
- {thumbElement}
415
- </SwitchPrimitive.Root>
416
-
417
- {/* Label */}
418
- <span className={cn('flex min-w-0 flex-col gap-1', end && 'flex-1')}>
419
- <span
420
- id={labelId}
421
- className={cn(
422
- // text-box trim recenters the letterforms against the track; the
423
- // track is taller than the label, so layout doesn't change.
424
- '[text-box:trim-both_cap_alphabetic] transition-[color] duration-fast',
425
- sizeClasses.text,
426
- description ? 'text-foreground weight-medium' : isChecked ? 'text-foreground' : 'text-muted-foreground',
427
- )}
428
- >
429
- {label}
430
- </span>
431
- {description && (
432
- <span
433
- id={descriptionId}
434
- className={cn(
435
- 'leading-relaxed text-muted-foreground',
436
- sizeClasses.variant === 'compact' ? 'text-caption-compact' : 'text-caption',
437
- )}
438
- >
439
- {description}
440
- </span>
441
- )}
442
- </span>
443
-
444
- {divider && <span aria-hidden className="pointer-events-none absolute inset-x-0 bottom-0 h-px bg-border/60" />}
445
- </div>
446
- )
447
- },
448
- ) as SwitchComponent
449
-
450
- Switch.displayName = 'Switch'
451
-
452
- interface SwitchGroupProps extends HTMLAttributes<HTMLFieldSetElement> {
453
- /** `Switch` rows. */
454
- children: ReactNode
455
- /** Pins every row to one step of the size ladder (see Sizes). Defaults to the surrounding SizeProvider. */
456
- size?: SizeVariant
457
- }
458
-
459
- // `Switch.Group`: the frame, hairlines and fluid hover around switch rows.
460
- const SwitchGroup = forwardRef<HTMLFieldSetElement, SwitchGroupProps>(
461
- ({ children, size, className, ...props }, ref) => {
462
- const containerRef = useRef<HTMLFieldSetElement | null>(null)
463
- const hover = useFluidHover(containerRef, { gapClick: false })
464
- const shape = useShape()
465
- const count = Children.toArray(children).filter(isValidElement).length
466
-
467
- const group = (
468
- <SwitchGroupContext.Provider value={{ registerItem: hover.registerItem, activeIndex: hover.activeIndex, count }}>
469
- <fieldset
470
- ref={node => {
471
- containerRef.current = node
472
- if (typeof ref === 'function') ref(node)
473
- else if (ref) ref.current = node
474
- }}
475
- onMouseEnter={hover.handlers.onMouseEnter}
476
- onMouseMove={hover.handlers.onMouseMove}
477
- onMouseLeave={hover.handlers.onMouseLeave}
478
- onClick={hover.handlers.onClick}
479
- className={cn(
480
- 'relative flex min-w-0 flex-col overflow-hidden border border-border/60 select-none',
481
- shape.container,
482
- className,
483
- )}
484
- {...props}
485
- >
486
- <FluidHoverHighlight hover={hover} className={cn('z-0', shape.container)} />
487
- <IndexedRows>{children}</IndexedRows>
488
- </fieldset>
489
- </SwitchGroupContext.Provider>
490
- )
491
-
492
- // A size prop pins every row in the group to one ladder step.
493
- return size ? <SizeProvider size={size}>{group}</SizeProvider> : group
494
- },
495
- )
496
-
497
- SwitchGroup.displayName = 'SwitchGroup'
498
-
499
- Object.assign(Switch, { Group: SwitchGroup })
500
-
501
- export type { SwitchGroupProps, SwitchProps }
502
- export { Switch, SwitchGroup }
503
-
504
- export default Switch