@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,581 +0,0 @@
1
- /*
2
- * Local addition (not part of Fluid Functionalism): the field and panel every
3
- * date and time picker shares. Not an item (a file in a group folder): the
4
- * pickers import it.
5
- *
6
- * The field is a text field on the shared field box (`useFieldBox` in
7
- * `lib/field-classes.ts`, `bordered` unless the picker's `variant` says
8
- * otherwise) showing the formatted value. Pressed, it opens its panel through Base UI's
9
- * Popover and the morph layer, with Combobox's options: goo out of the field
10
- * by default, or in place over it (`effect="morph"` with `hideSource`), the
11
- * panel's header landing where the field was. On a phone-width screen the
12
- * panel is the Sheet item instead, from the bottom edge.
13
- *
14
- * With an `editor` (DatePicker's `editable`) the field is a box around that
15
- * text control instead of a button, and only its leading icon, an
16
- * `InputAction`, opens the panel; the panel still anchors to and grows out
17
- * of the whole field. `readOnly` shows the value and never opens.
18
- *
19
- * Form wiring: `controlRef` / `controlProps` reach the field's button (an
20
- * editable picker puts its own on its input), and `formValues` render
21
- * visually hidden inputs carrying the value for a native form; one the
22
- * browser reports as invalid hands focus to the field.
23
- */
24
-
25
- import { Popover } from '@base-ui/react/popover'
26
- import {
27
- type AriaAttributes,
28
- type ButtonHTMLAttributes,
29
- type FocusEvent,
30
- forwardRef,
31
- type HTMLAttributes,
32
- type ReactElement,
33
- type ReactNode,
34
- type Ref,
35
- type RefObject,
36
- useCallback,
37
- useMemo,
38
- useRef,
39
- useState,
40
- } from 'react'
41
- import { type FieldVariant, fieldIconClasses, useFieldBox, useFieldState } from '../../../lib/field-classes'
42
- import { type IconName, useIcon } from '../../../lib/icon-context'
43
- import { MorphSurface } from '../../../lib/morph-layers'
44
- import { useShape } from '../../../lib/shape-context'
45
- import { type SizeVariant, useSize } from '../../../lib/size-context'
46
- import { SURFACE_BG, SURFACE_SHADOW } from '../../../lib/surface-classes'
47
- import { SurfaceProvider, useSurface } from '../../../lib/surface-context'
48
- import { useControllableState } from '../../../lib/use-controllable-state'
49
- import { useIsMobile } from '../../../lib/use-is-mobile'
50
- import {
51
- inPlaceOffset,
52
- type MorphEffect,
53
- type MorphFrom,
54
- type MorphTier,
55
- opensInPlace,
56
- useMorph,
57
- useMorphOrigin,
58
- } from '../../../lib/use-morph'
59
- import { cn } from '../../../lib/utils'
60
- import { SizeProvider } from '../../../primitives/sizes'
61
- import Button from '../../button'
62
- import Sheet from '../../overlays/sheet'
63
- import Input, { InputAction, InputAdornment, type InputProps } from '../input'
64
-
65
- /** Attributes for the element a picker's field renders as its control (its button, or an editable field's input), `data-*` included. */
66
- type PickerControlAttributes = Omit<
67
- HTMLAttributes<HTMLElement>,
68
- 'children' | 'dangerouslySetInnerHTML' | 'defaultValue' | 'defaultChecked'
69
- > & {
70
- /** An editable field's input: browser autofill hint. Defaults to `"off"`. */
71
- autoComplete?: string
72
- [data: `data-${string}`]: string | number | boolean | undefined
73
- }
74
-
75
- /** The form and accessibility props every picker forwards to its field's control. */
76
- interface PickerControlProps {
77
- /** Marks the value required: a native form won't submit while it is empty (and an editable field's input carries `required`). Defaults to the surrounding Field's `required`. */
78
- required?: boolean
79
- /** Called when the field's control (its button, or an editable field's input) loses focus, as when the panel takes it. */
80
- onBlur?: (event: FocusEvent<HTMLElement>) => void
81
- /** Names the field's control for assistive tech, in place of its label. */
82
- 'aria-label'?: string
83
- /** Ids of the elements naming the field's control, in place of its own label. */
84
- 'aria-labelledby'?: string
85
- /** Ids of the elements describing the field's control (a hint, an error message). */
86
- 'aria-describedby'?: string
87
- /** Marks the value invalid, as `invalid` does. */
88
- 'aria-invalid'?: AriaAttributes['aria-invalid']
89
- /** Attributes for the field's control: the button that opens the panel, or an `editable` field's input (`data-*`, `autoFocus`, `tabIndex`, handlers, which run after the picker's own; an editable field's input also takes `autoComplete` and `inputMode`, which replace its defaults of `"off"` and `"numeric"`). On an editable field the masked input owns `onChange`, so a caller's one never runs; only `onFocus`, `onBlur` and `onKeyDown` chain, the caller's `onKeyDown` first, and its `preventDefault()` skips the mask's own key handling). */
90
- controlProps?: PickerControlAttributes
91
- }
92
-
93
- /** `invalid`, or `true` when `aria-invalid` marks the value invalid (unset stays unset, for a surrounding Field). */
94
- const invalidOf = (invalid: boolean | undefined, ariaInvalid: AriaAttributes['aria-invalid']) =>
95
- ariaInvalid !== undefined && ariaInvalid !== false && ariaInvalid !== 'false' ? true : invalid
96
-
97
- /** The control's attributes from a picker's props: `controlProps`, then the named props over them, `onBlur` after its own. */
98
- function controlAttributes({
99
- controlProps,
100
- onBlur,
101
- 'aria-label': ariaLabel,
102
- 'aria-labelledby': ariaLabelledBy,
103
- 'aria-describedby': ariaDescribedBy,
104
- }: PickerControlProps): PickerControlAttributes {
105
- return {
106
- ...controlProps,
107
- ...(ariaLabel !== undefined && { 'aria-label': ariaLabel }),
108
- ...(ariaLabelledBy !== undefined && { 'aria-labelledby': ariaLabelledBy }),
109
- ...(ariaDescribedBy !== undefined && { 'aria-describedby': ariaDescribedBy }),
110
- ...(onBlur && {
111
- onBlur: (event: FocusEvent<HTMLElement>) => {
112
- controlProps?.onBlur?.(event)
113
- onBlur(event)
114
- },
115
- }),
116
- }
117
- }
118
-
119
- /** Hands an element to every ref given. */
120
- function assignRefs<T>(...refs: (Ref<T> | RefObject<unknown> | undefined)[]) {
121
- return (node: T | null) => {
122
- for (const ref of refs) {
123
- if (typeof ref === 'function') ref(node)
124
- else if (ref) (ref as { current: T | null }).current = node
125
- }
126
- }
127
- }
128
-
129
- /** The field's own classes with `controlProps`, whose `className` joins them. */
130
- function fieldControl(className: string | undefined, controlProps: PickerControlAttributes | undefined) {
131
- return { ...controlProps, className: cn(className, controlProps?.className) }
132
- }
133
-
134
- /** One value a native form submits: `name` (when given) and the text it carries; `slot` tells the entries apart. */
135
- interface PickerFormValue {
136
- slot: 'value' | 'start' | 'end'
137
- name?: string
138
- value: string
139
- }
140
-
141
- interface PickerShellProps {
142
- open?: boolean
143
- defaultOpen?: boolean
144
- onOpenChange?: (open: boolean) => void
145
- size?: SizeVariant
146
- variant?: FieldVariant
147
- invalid?: boolean
148
- disabled?: boolean
149
- /** The field's leading icon. */
150
- icon: IconName
151
- /** The formatted value; empty shows the placeholder. */
152
- display: ReactNode
153
- placeholder?: string
154
- /** The panel header's inputs; the shell adds the close button after them. */
155
- header: ReactNode
156
- /** What the panel focuses when it opens on a desktop (its header input). */
157
- initialFocus?: RefObject<HTMLElement | null>
158
- /** Accessible name of the close button. */
159
- closeLabel?: string
160
- id?: string
161
- dir?: string
162
- /** Classes for the field. */
163
- className?: string
164
- /** Classes for the panel on a desktop: its width. */
165
- popupClassName?: string
166
- /** The desktop panel's morph (see Morph); a phone's sheet grows from its edge. */
167
- from?: MorphFrom
168
- effect?: MorphEffect
169
- hideSource?: boolean
170
- tier?: MorphTier
171
- /** The field's own text control (an editable picker): the field becomes a box around it, and its icon a button that opens the panel. */
172
- editor?: ReactNode
173
- /** Accessible name of that icon button. Defaults to `"Open calendar"`. */
174
- triggerLabel?: string
175
- /** Shows the value and never opens. */
176
- readOnly?: boolean
177
- /** Receives the field's button (a plain field; an editable picker refs its own input). */
178
- controlRef?: Ref<HTMLButtonElement>
179
- /** Attributes for the field's button (a plain field; an editable picker puts its own on its input). */
180
- controlProps?: PickerControlAttributes
181
- /** What a native form submits: a visually hidden input per entry, rendered once one has a `name` or the field is `required`. */
182
- formValues?: PickerFormValue[]
183
- /** Marks the hidden inputs required. Defaults to the surrounding Field's `required`. */
184
- required?: boolean
185
- /** The panel body under the header. */
186
- children: ReactNode
187
- }
188
-
189
- /** The field and its panel: a popover out of the field (or in place of it), or a bottom sheet on a phone. */
190
- function PickerShell({
191
- open: openProp,
192
- defaultOpen = false,
193
- onOpenChange,
194
- size,
195
- formValues,
196
- required,
197
- ...props
198
- }: PickerShellProps) {
199
- const [open, setOpenState] = useControllableState(openProp, defaultOpen, onOpenChange)
200
- const setOpen = (next: boolean) => {
201
- if (next && props.readOnly) return
202
- setOpenState(next)
203
- }
204
- const fieldRef = useRef<HTMLElement>(null)
205
- const mobile = useIsMobile(640)
206
- const shell = mobile ? (
207
- <PickerSheet open={open} setOpen={setOpen} fieldRef={fieldRef} {...props} />
208
- ) : (
209
- <PickerPopover open={open} setOpen={setOpen} fieldRef={fieldRef} {...props} />
210
- )
211
- const inputs = formValues && (
212
- <PickerFormInputs values={formValues} required={required} disabled={props.disabled} fieldRef={fieldRef} />
213
- )
214
- const content = inputs ? (
215
- <>
216
- {shell}
217
- {inputs}
218
- </>
219
- ) : (
220
- shell
221
- )
222
- // A size pins the field and the portalled panel (context crosses portals).
223
- return size ? <SizeProvider size={size}>{content}</SizeProvider> : content
224
- }
225
-
226
- /**
227
- * The value for a native form: visually hidden inputs, out of the tab order.
228
- * They are real text inputs, not `type="hidden"`, so `required` stops a
229
- * submit; when the browser reports one, focus goes to the field.
230
- */
231
- function PickerFormInputs({
232
- values,
233
- required,
234
- disabled,
235
- fieldRef,
236
- }: {
237
- values: PickerFormValue[]
238
- required?: boolean
239
- disabled?: boolean
240
- fieldRef: RefObject<HTMLElement>
241
- }) {
242
- const field = useFieldState()
243
- const isRequired = required ?? field?.required ?? false
244
- if (!isRequired && !values.some(v => v.name)) return null
245
- const focusField = () => {
246
- const el = fieldRef.current
247
- ;(el instanceof HTMLButtonElement ? el : el?.querySelector('input'))?.focus()
248
- }
249
- return values.map(({ slot, name, value }) => (
250
- <input
251
- key={slot}
252
- aria-hidden
253
- tabIndex={-1}
254
- name={name}
255
- value={value}
256
- required={isRequired}
257
- disabled={disabled ?? field?.disabled}
258
- onChange={() => {}}
259
- onFocus={focusField}
260
- className="sr-only"
261
- />
262
- ))
263
- }
264
-
265
- type PanelProps = Omit<
266
- PickerShellProps,
267
- 'open' | 'defaultOpen' | 'onOpenChange' | 'size' | 'formValues' | 'required'
268
- > & {
269
- open: boolean
270
- setOpen: (open: boolean) => void
271
- /** The field's element: its button, or an editable field's box. */
272
- fieldRef: RefObject<HTMLElement>
273
- }
274
-
275
- type PickerFieldProps = Pick<
276
- PanelProps,
277
- 'icon' | 'display' | 'placeholder' | 'variant' | 'invalid' | 'disabled' | 'readOnly' | 'id' | 'className'
278
- > &
279
- Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'className'>
280
-
281
- // Forwards its ref: Base UI anchors the panel to the field through it.
282
- const PickerField = forwardRef<HTMLButtonElement, PickerFieldProps>(
283
- ({ icon, display, placeholder, variant = 'bordered', invalid, disabled, readOnly, id, className, ...props }, ref) => {
284
- const Icon = useIcon(icon)
285
- const { size: sizeClasses, props: boxProps } = useFieldBox({ variant, invalid, disabled, readOnly })
286
-
287
- return (
288
- <button
289
- ref={ref}
290
- type="button"
291
- id={id}
292
- disabled={disabled}
293
- aria-invalid={invalid || undefined}
294
- {...boxProps}
295
- // Base UI's trigger props (open state, handlers, aria) arrive here.
296
- {...props}
297
- className={cn(
298
- boxProps.className,
299
- 'flex w-full min-w-0 items-center text-left outline-none focus-visible:ring-focus-ring',
300
- // A read-only field never opens, and doesn't look like it would.
301
- readOnly ? 'cursor-default' : 'cursor-pointer',
302
- sizeClasses.gap,
303
- sizeClasses.control,
304
- className,
305
- )}
306
- >
307
- <Icon size={sizeClasses.icon} strokeWidth={1.5} className={fieldIconClasses} />
308
- <span
309
- className={cn('flex-1 truncate', sizeClasses.text, display ? 'text-foreground' : 'text-muted-foreground')}
310
- >
311
- {display || placeholder}
312
- </span>
313
- </button>
314
- )
315
- },
316
- )
317
- PickerField.displayName = 'PickerField'
318
-
319
- type EditableFieldProps = Pick<
320
- PanelProps,
321
- 'icon' | 'variant' | 'invalid' | 'disabled' | 'readOnly' | 'className' | 'editor' | 'triggerLabel'
322
- > & {
323
- /** Wraps the icon button in the panel's trigger. */
324
- trigger: (button: ReactNode) => ReactNode
325
- }
326
-
327
- /** An editable picker's field: its text control, led by the icon button that opens the panel. */
328
- const EditableField = forwardRef<HTMLElement, EditableFieldProps>(
329
- (
330
- {
331
- icon,
332
- variant = 'bordered',
333
- invalid,
334
- disabled,
335
- readOnly,
336
- className,
337
- editor,
338
- triggerLabel = 'Open calendar',
339
- trigger,
340
- },
341
- ref,
342
- ) => {
343
- const Icon = useIcon(icon)
344
- const { size: sizeClasses, props: boxProps } = useFieldBox({ variant, invalid, disabled, readOnly })
345
- return (
346
- <div
347
- ref={ref as Ref<HTMLDivElement>}
348
- {...boxProps}
349
- className={cn(
350
- boxProps.className,
351
- 'flex w-full min-w-0 items-center',
352
- sizeClasses.gap,
353
- sizeClasses.control,
354
- className,
355
- )}
356
- >
357
- <InputAdornment>
358
- {trigger(<InputAction label={triggerLabel} icon={Icon} disabled={disabled || readOnly} />)}
359
- </InputAdornment>
360
- {editor}
361
- </div>
362
- )
363
- },
364
- )
365
- EditableField.displayName = 'EditableField'
366
-
367
- function PanelHeader({
368
- header,
369
- closeLabel = 'Close',
370
- close,
371
- }: {
372
- header: ReactNode
373
- closeLabel?: string
374
- close: () => void
375
- }) {
376
- const X = useIcon('x')
377
- const sizeClasses = useSize()
378
- return (
379
- <div className="flex items-center gap-1 border-b border-border pb-1">
380
- <div className="flex min-w-0 flex-1 items-center">{header}</div>
381
- <Button variant="ghost" size="icon-sm" aria-label={closeLabel} onClick={close}>
382
- <X size={sizeClasses.icon} strokeWidth={1.5} />
383
- </Button>
384
- </div>
385
- )
386
- }
387
-
388
- function PickerPopover({
389
- open,
390
- setOpen,
391
- header,
392
- initialFocus,
393
- closeLabel,
394
- dir,
395
- popupClassName,
396
- from,
397
- effect,
398
- hideSource,
399
- tier = 'moderate',
400
- children,
401
- editor,
402
- triggerLabel,
403
- fieldRef,
404
- controlRef,
405
- controlProps,
406
- ...field
407
- }: PanelProps) {
408
- const triggerRef = useMemo(() => assignRefs<HTMLButtonElement>(fieldRef, controlRef), [fieldRef, controlRef])
409
- const { origin, capture } = useMorphOrigin()
410
- const morph = useMorph(open, origin, { from, effect, hideSource, tier })
411
- const shape = useShape()
412
- const level = Math.min(useSurface() + 2, 8)
413
-
414
- const handleOpenChange = useCallback(
415
- (next: boolean, details: { reason?: string; trigger?: Element; event?: Event }) => {
416
- // Pressing or focusing the editable field's own text is no reason to
417
- // close: the panel belongs to that field.
418
- if (!next && editor && (details.reason === 'outside-press' || details.reason === 'focus-out')) {
419
- const event = details.event as (Event & { relatedTarget?: EventTarget | null }) | undefined
420
- const target = (event?.relatedTarget ?? event?.target) as Node | null | undefined
421
- if (target && fieldRef.current?.contains(target)) return
422
- }
423
- // An editable field's panel grows out of the whole field, not its icon.
424
- if (next) capture(editor ? { event: details.event, trigger: fieldRef.current ?? undefined } : details)
425
- setOpen(next)
426
- },
427
- [capture, setOpen, editor],
428
- )
429
-
430
- return (
431
- // Non-modal: the page keeps scrolling and the panel follows its field.
432
- <Popover.Root open={open} onOpenChange={handleOpenChange} modal={false}>
433
- {editor ? (
434
- <EditableField
435
- ref={fieldRef}
436
- {...field}
437
- editor={editor}
438
- triggerLabel={triggerLabel}
439
- trigger={button => <Popover.Trigger disabled={field.disabled} render={button as ReactElement} />}
440
- />
441
- ) : (
442
- <Popover.Trigger
443
- ref={triggerRef}
444
- disabled={field.disabled}
445
- render={<PickerField {...field} {...fieldControl(field.className, controlProps)} />}
446
- />
447
- )}
448
- <Popover.Portal>
449
- <Popover.Positioner
450
- anchor={editor ? fieldRef : undefined}
451
- side="bottom"
452
- align="start"
453
- sideOffset={opensInPlace({ effect, hideSource }) ? inPlaceOffset : 6}
454
- className="z-50 outline-none"
455
- >
456
- <Popover.Popup ref={morph.popupRef} initialFocus={initialFocus} className="relative outline-none">
457
- <SurfaceProvider value={level}>
458
- <MorphSurface
459
- morph={morph}
460
- bg={SURFACE_BG[level]}
461
- shadow={SURFACE_SHADOW[3]}
462
- radius={shape.container}
463
- className={cn('flex max-w-[calc(100vw-1rem)] flex-col gap-1 p-1', popupClassName)}
464
- >
465
- <div dir={dir} className="flex min-h-0 flex-col gap-1">
466
- <PanelHeader header={header} closeLabel={closeLabel} close={() => setOpen(false)} />
467
- {children}
468
- </div>
469
- </MorphSurface>
470
- </SurfaceProvider>
471
- </Popover.Popup>
472
- </Popover.Positioner>
473
- </Popover.Portal>
474
- </Popover.Root>
475
- )
476
- }
477
-
478
- function PickerSheet({
479
- open,
480
- setOpen,
481
- header,
482
- closeLabel,
483
- dir,
484
- children,
485
- editor,
486
- triggerLabel,
487
- fieldRef,
488
- controlRef,
489
- controlProps,
490
- ...field
491
- }: PanelProps) {
492
- const triggerRef = useMemo(() => assignRefs<HTMLButtonElement>(fieldRef, controlRef), [fieldRef, controlRef])
493
- const {
494
- initialFocus: _focus,
495
- popupClassName: _width,
496
- from: _from,
497
- effect: _effect,
498
- hideSource: _hide,
499
- tier: _tier,
500
- ...fieldProps
501
- } = field
502
- return (
503
- <Sheet open={open} onOpenChange={setOpen}>
504
- {editor ? (
505
- <EditableField
506
- ref={fieldRef}
507
- {...fieldProps}
508
- editor={editor}
509
- triggerLabel={triggerLabel}
510
- trigger={button => <Sheet.Trigger disabled={field.disabled} render={button as ReactElement} />}
511
- />
512
- ) : (
513
- <Sheet.Trigger
514
- ref={triggerRef}
515
- disabled={field.disabled}
516
- render={<PickerField {...fieldProps} {...fieldControl(fieldProps.className, controlProps)} />}
517
- />
518
- )}
519
- <Sheet.Content className="gap-2 p-3 pt-3">
520
- <div dir={dir} className="flex min-h-0 flex-col gap-2">
521
- <PanelHeader header={header} closeLabel={closeLabel} close={() => setOpen(false)} />
522
- {children}
523
- </div>
524
- </Sheet.Content>
525
- </Sheet>
526
- )
527
- }
528
-
529
- interface PickerInputProps extends Omit<InputProps, 'value' | 'defaultValue' | 'onChange'> {
530
- /** The value as the field shows it, while nothing is being typed. */
531
- formatted: string
532
- /** Reads typed text and commits it; returns whether it could. */
533
- onText: (text: string) => boolean
534
- /** Enter, after a valid entry: the pickers close. */
535
- onEnter?: () => void
536
- }
537
-
538
- /**
539
- * A header input: shows the formatted value, selects it all on focus, and
540
- * commits what is typed as soon as it reads as a value (marking it invalid
541
- * until then). Leaving it restores the formatted value. Hover and focus fill
542
- * it without the field ring.
543
- */
544
- const PickerInput = forwardRef<HTMLInputElement, PickerInputProps>(
545
- ({ formatted, onText, onEnter, onFocus, onBlur, onKeyDown, className, ...props }, ref) => {
546
- const [draft, setDraft] = useState<string | null>(null)
547
- const [invalid, setInvalid] = useState(false)
548
- return (
549
- <Input
550
- ref={ref}
551
- {...props}
552
- // The header is already framed by the panel: hover and focus change
553
- // the fill only (an invalid entry keeps its destructive ring).
554
- className={cn('hover:ring-transparent focus-within:ring-transparent data-[active]:ring-transparent', className)}
555
- value={draft ?? formatted}
556
- invalid={invalid}
557
- onChange={text => {
558
- setDraft(text)
559
- setInvalid(!onText(text))
560
- }}
561
- onFocus={e => {
562
- e.currentTarget.select()
563
- onFocus?.(e)
564
- }}
565
- onBlur={e => {
566
- setDraft(null)
567
- setInvalid(false)
568
- onBlur?.(e)
569
- }}
570
- onKeyDown={e => {
571
- if (e.key === 'Enter' && !invalid) onEnter?.()
572
- onKeyDown?.(e)
573
- }}
574
- />
575
- )
576
- },
577
- )
578
- PickerInput.displayName = 'PickerInput'
579
-
580
- export type { PickerControlAttributes, PickerControlProps, PickerFormValue, PickerShellProps }
581
- export { assignRefs, controlAttributes, invalidOf, PickerInput, PickerShell }
@@ -1,94 +0,0 @@
1
- /*
2
- * Local addition (not part of Fluid Functionalism): the hour column (its
3
- * AM/PM folded in on a 12-hour clock) and the minute column the date picker
4
- * (with time) and the time picker share. Not an item (a file in a group folder).
5
- */
6
-
7
- import { format, type Locale } from 'date-fns'
8
- import { useMemo } from 'react'
9
- import { fieldLabel, type HourCycle } from '../../../lib/date-locale'
10
- import { ScrollColumn } from '../../../lib/scroll-column'
11
- import { cn } from '../../../lib/utils'
12
-
13
- interface Time {
14
- hours: number
15
- minutes: number
16
- }
17
-
18
- interface TimeColumnsProps {
19
- value: Time | null
20
- onValueChange: (time: Time) => void
21
- hourCycle: HourCycle
22
- minuteStep: number
23
- locale: Locale
24
- orientation: 'vertical' | 'horizontal'
25
- /** Columns share the row's width equally instead of keeping their narrow fixed widths. Defaults to `false`. */
26
- fill?: boolean
27
- /** Accessible names of the columns. Default to the locale's names for the fields. */
28
- labels?: { hour?: string; minute?: string }
29
- }
30
-
31
- const pad = (n: number) => String(n).padStart(2, '0')
32
-
33
- /** Columns for the hour (with its AM/PM on a 12-hour clock) and the minute; a row of them divides itself. */
34
- function TimeColumns({
35
- value,
36
- onValueChange,
37
- hourCycle,
38
- minuteStep,
39
- locale,
40
- orientation,
41
- fill = false,
42
- labels,
43
- }: TimeColumnsProps) {
44
- const twelve = hourCycle === 'h12' || hourCycle === 'h11'
45
- const hours = value?.hours ?? null
46
- const minutes = value?.minutes ?? 0
47
-
48
- const hourOptions = useMemo(
49
- () =>
50
- Array.from({ length: 24 }, (_, h) => ({
51
- value: h,
52
- // "12 AM" … "11 PM" (h11: "0 AM" … "11 PM"), in the locale's words.
53
- label: twelve ? format(new Date(2000, 0, 1, h), hourCycle === 'h11' ? 'K a' : 'h a', { locale }) : pad(h),
54
- })),
55
- [twelve, hourCycle, locale],
56
- )
57
- const minuteOptions = useMemo(
58
- () =>
59
- Array.from({ length: Math.ceil(60 / minuteStep) }, (_, i) => ({
60
- value: i * minuteStep,
61
- label: pad(i * minuteStep),
62
- })),
63
- [minuteStep],
64
- )
65
-
66
- const vertical = orientation === 'vertical'
67
- // Beside a calendar: narrower than its month and year columns, an hour
68
- // with its AM/PM a little wider. On their own (`fill`): an equal share.
69
- const width = (fixed: string) => (!vertical ? 'w-full' : fill ? 'min-w-0 flex-1' : cn('shrink-0', fixed))
70
-
71
- return (
72
- <>
73
- <ScrollColumn
74
- label={labels?.hour ?? fieldLabel(locale, 'hour')}
75
- options={hourOptions}
76
- value={hours}
77
- onValueChange={h => onValueChange({ hours: h, minutes })}
78
- orientation={orientation}
79
- className={width(twelve ? 'w-15' : 'w-12')}
80
- />
81
- <ScrollColumn
82
- label={labels?.minute ?? fieldLabel(locale, 'minute')}
83
- options={minuteOptions}
84
- value={hours === null ? null : minutes}
85
- onValueChange={m => onValueChange({ hours: hours ?? 0, minutes: m })}
86
- orientation={orientation}
87
- className={width('w-12')}
88
- />
89
- </>
90
- )
91
- }
92
-
93
- export type { Time }
94
- export { pad, TimeColumns }