@remix-run/ui 0.2.0 → 0.4.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 (395) hide show
  1. package/README.md +50 -164
  2. package/dist/accordion/index.d.ts +46 -0
  3. package/dist/accordion/index.js +142 -0
  4. package/dist/accordion/index.js.map +1 -0
  5. package/dist/accordion/primitives.d.ts +104 -0
  6. package/dist/accordion/primitives.js +312 -0
  7. package/dist/accordion/primitives.js.map +1 -0
  8. package/dist/{components/anchor/anchor.d.ts → anchor/index.d.ts} +8 -1
  9. package/dist/{components/anchor/anchor.js → anchor/index.js} +31 -12
  10. package/dist/anchor/index.js.map +1 -0
  11. package/dist/animation/demos/aspect-ratio.d.ts +2 -0
  12. package/dist/animation/demos/aspect-ratio.js +69 -0
  13. package/dist/animation/demos/aspect-ratio.js.map +1 -0
  14. package/dist/animation/demos/bouncy-switch.d.ts +2 -0
  15. package/dist/animation/demos/bouncy-switch.js +36 -0
  16. package/dist/animation/demos/bouncy-switch.js.map +1 -0
  17. package/dist/animation/demos/color-interpolation.d.ts +1 -0
  18. package/dist/animation/demos/color-interpolation.js +53 -0
  19. package/dist/animation/demos/color-interpolation.js.map +1 -0
  20. package/dist/animation/demos/cube.d.ts +2 -0
  21. package/dist/animation/demos/cube.js +86 -0
  22. package/dist/animation/demos/cube.js.map +1 -0
  23. package/dist/animation/demos/default-animate.d.ts +2 -0
  24. package/dist/animation/demos/default-animate.js +89 -0
  25. package/dist/animation/demos/default-animate.js.map +1 -0
  26. package/dist/animation/demos/drag-release.d.ts +24 -0
  27. package/dist/animation/demos/drag-release.js +96 -0
  28. package/dist/animation/demos/drag-release.js.map +1 -0
  29. package/dist/animation/demos/enter.d.ts +1 -0
  30. package/dist/animation/demos/enter.js +19 -0
  31. package/dist/animation/demos/enter.js.map +1 -0
  32. package/dist/animation/demos/exit.d.ts +2 -0
  33. package/dist/animation/demos/exit.js +58 -0
  34. package/dist/animation/demos/exit.js.map +1 -0
  35. package/dist/animation/demos/flip-toggle.d.ts +2 -0
  36. package/dist/animation/demos/flip-toggle.js +37 -0
  37. package/dist/animation/demos/flip-toggle.js.map +1 -0
  38. package/dist/animation/demos/hold-to-confirm.d.ts +13 -0
  39. package/dist/animation/demos/hold-to-confirm.js +211 -0
  40. package/dist/animation/demos/hold-to-confirm.js.map +1 -0
  41. package/dist/animation/demos/html-content.d.ts +2 -0
  42. package/dist/animation/demos/html-content.js +30 -0
  43. package/dist/animation/demos/html-content.js.map +1 -0
  44. package/dist/animation/demos/interruptible-keyframes.d.ts +1 -0
  45. package/dist/animation/demos/interruptible-keyframes.js +48 -0
  46. package/dist/animation/demos/interruptible-keyframes.js.map +1 -0
  47. package/dist/animation/demos/keyframes.d.ts +1 -0
  48. package/dist/animation/demos/keyframes.js +24 -0
  49. package/dist/animation/demos/keyframes.js.map +1 -0
  50. package/dist/animation/demos/material-ripple.d.ts +2 -0
  51. package/dist/animation/demos/material-ripple.js +127 -0
  52. package/dist/animation/demos/material-ripple.js.map +1 -0
  53. package/dist/animation/demos/mixin-presence-list.d.ts +2 -0
  54. package/dist/animation/demos/mixin-presence-list.js +88 -0
  55. package/dist/animation/demos/mixin-presence-list.js.map +1 -0
  56. package/dist/animation/demos/mixin-reclaim.d.ts +2 -0
  57. package/dist/animation/demos/mixin-reclaim.js +90 -0
  58. package/dist/animation/demos/mixin-reclaim.js.map +1 -0
  59. package/dist/animation/demos/multi-state-badge.d.ts +2 -0
  60. package/dist/animation/demos/multi-state-badge.js +231 -0
  61. package/dist/animation/demos/multi-state-badge.js.map +1 -0
  62. package/dist/animation/demos/press.d.ts +2 -0
  63. package/dist/animation/demos/press.js +63 -0
  64. package/dist/animation/demos/press.js.map +1 -0
  65. package/dist/animation/demos/reordering.d.ts +2 -0
  66. package/dist/animation/demos/reordering.js +53 -0
  67. package/dist/animation/demos/reordering.js.map +1 -0
  68. package/dist/animation/demos/rolling-square.d.ts +2 -0
  69. package/dist/animation/demos/rolling-square.js +42 -0
  70. package/dist/animation/demos/rolling-square.js.map +1 -0
  71. package/dist/animation/demos/rotate.d.ts +1 -0
  72. package/dist/animation/demos/rotate.js +18 -0
  73. package/dist/animation/demos/rotate.js.map +1 -0
  74. package/dist/animation/demos/shared-layout.d.ts +2 -0
  75. package/dist/animation/demos/shared-layout.js +114 -0
  76. package/dist/animation/demos/shared-layout.js.map +1 -0
  77. package/dist/animation/demos/transition-options.d.ts +1 -0
  78. package/dist/animation/demos/transition-options.js +21 -0
  79. package/dist/animation/demos/transition-options.js.map +1 -0
  80. package/dist/animation/spring.d.ts +22 -0
  81. package/dist/animation/spring.js +22 -0
  82. package/dist/animation/spring.js.map +1 -1
  83. package/dist/{components/breadcrumbs/breadcrumbs.js → breadcrumbs/index.js} +19 -19
  84. package/dist/breadcrumbs/index.js.map +1 -0
  85. package/dist/button/index.d.ts +15 -0
  86. package/dist/button/index.js +128 -0
  87. package/dist/button/index.js.map +1 -0
  88. package/dist/checkbox/index.d.ts +14 -0
  89. package/dist/checkbox/index.js +125 -0
  90. package/dist/checkbox/index.js.map +1 -0
  91. package/dist/combobox/index.d.ts +21 -0
  92. package/dist/combobox/index.js +58 -0
  93. package/dist/combobox/index.js.map +1 -0
  94. package/dist/{components/combobox/combobox.d.ts → combobox/primitives.d.ts} +3 -7
  95. package/dist/{components/combobox/combobox.js → combobox/primitives.js} +8 -61
  96. package/dist/combobox/primitives.js.map +1 -0
  97. package/dist/input/index.d.ts +13 -0
  98. package/dist/input/index.js +121 -0
  99. package/dist/input/index.js.map +1 -0
  100. package/dist/listbox/flash-attribute.js.map +1 -0
  101. package/dist/{components/listbox/listbox.d.ts → listbox/index.d.ts} +2 -6
  102. package/dist/{components/listbox/listbox.js → listbox/index.js} +4 -82
  103. package/dist/listbox/index.js.map +1 -0
  104. package/dist/menu/hover-aim.js.map +1 -0
  105. package/dist/menu/index.d.ts +42 -0
  106. package/dist/menu/index.js +250 -0
  107. package/dist/menu/index.js.map +1 -0
  108. package/dist/{components/menu/menu.d.ts → menu/primitives.d.ts} +6 -32
  109. package/dist/{components/menu/menu.js → menu/primitives.js} +117 -279
  110. package/dist/menu/primitives.js.map +1 -0
  111. package/dist/{components/popover/popover.d.ts → popover/index.d.ts} +3 -5
  112. package/dist/{components/popover/popover.js → popover/index.js} +15 -51
  113. package/dist/popover/index.js.map +1 -0
  114. package/dist/{interactions/outside-click/outside-click-mixin.js → popover/outside-click.js} +1 -1
  115. package/dist/popover/outside-click.js.map +1 -0
  116. package/dist/popover/scroll-lock.d.ts +1 -0
  117. package/dist/{utils → popover}/scroll-lock.js +0 -18
  118. package/dist/popover/scroll-lock.js.map +1 -0
  119. package/dist/radio/index.d.ts +12 -0
  120. package/dist/radio/index.js +77 -0
  121. package/dist/radio/index.js.map +1 -0
  122. package/dist/runtime/client-entries.d.ts +1 -2
  123. package/dist/runtime/client-entries.js.map +1 -1
  124. package/dist/runtime/component.d.ts +2 -2
  125. package/dist/runtime/component.js +1 -1
  126. package/dist/runtime/component.js.map +1 -1
  127. package/dist/runtime/diff-dom.js +194 -21
  128. package/dist/runtime/diff-dom.js.map +1 -1
  129. package/dist/runtime/frame.d.ts +7 -0
  130. package/dist/runtime/frame.js +176 -41
  131. package/dist/runtime/frame.js.map +1 -1
  132. package/dist/runtime/jsx.d.ts +2 -3
  133. package/dist/runtime/jsx.js.map +1 -1
  134. package/dist/runtime/reconcile.js +11 -5
  135. package/dist/runtime/reconcile.js.map +1 -1
  136. package/dist/runtime/vdom.js +3 -0
  137. package/dist/runtime/vdom.js.map +1 -1
  138. package/dist/select/index.d.ts +19 -0
  139. package/dist/select/index.js +95 -0
  140. package/dist/select/index.js.map +1 -0
  141. package/dist/select/keydown.js.map +1 -0
  142. package/dist/{components/select/select.d.ts → select/primitives.d.ts} +4 -6
  143. package/dist/{components/select/select.js → select/primitives.js} +12 -64
  144. package/dist/select/primitives.js.map +1 -0
  145. package/dist/server/stream.js +5 -4
  146. package/dist/server/stream.js.map +1 -1
  147. package/dist/shared/focus-styles.d.ts +1 -0
  148. package/dist/shared/focus-styles.js +2 -0
  149. package/dist/shared/focus-styles.js.map +1 -0
  150. package/dist/shared/icons.d.ts +9 -0
  151. package/dist/shared/icons.js +42 -0
  152. package/dist/shared/icons.js.map +1 -0
  153. package/dist/shared/listbox-popover-styles.d.ts +6 -0
  154. package/dist/shared/listbox-popover-styles.js +137 -0
  155. package/dist/shared/listbox-popover-styles.js.map +1 -0
  156. package/dist/shared/style-values.d.ts +78 -0
  157. package/dist/{theme/presets/rmx-01/index.js → shared/style-values.js} +3 -34
  158. package/dist/shared/style-values.js.map +1 -0
  159. package/dist/{interactions/typeahead/typeahead-mixin.js → shared/typeahead.js} +1 -1
  160. package/dist/shared/typeahead.js.map +1 -0
  161. package/dist/shared/wait-for-css-transition.js.map +1 -0
  162. package/dist/shared/wait.js.map +1 -0
  163. package/dist/style/style.js +27 -10
  164. package/dist/style/style.js.map +1 -1
  165. package/dist/tabs/index.d.ts +32 -0
  166. package/dist/tabs/index.js +157 -0
  167. package/dist/tabs/index.js.map +1 -0
  168. package/dist/tabs/primitives.d.ts +57 -0
  169. package/dist/tabs/primitives.js +238 -0
  170. package/dist/tabs/primitives.js.map +1 -0
  171. package/dist/toggle/index.d.ts +9 -0
  172. package/dist/toggle/index.js +108 -0
  173. package/dist/toggle/index.js.map +1 -0
  174. package/dist/toggle/primitives.d.ts +29 -0
  175. package/dist/toggle/primitives.js +127 -0
  176. package/dist/toggle/primitives.js.map +1 -0
  177. package/package.json +74 -45
  178. package/src/{components/accordion → accordion}/README.md +50 -14
  179. package/src/accordion/index.tsx +285 -0
  180. package/src/accordion/primitives.tsx +512 -0
  181. package/src/{components/anchor → anchor}/README.md +48 -5
  182. package/src/{components/anchor/anchor.ts → anchor/index.ts} +53 -12
  183. package/src/animation/demos/aspect-ratio.tsx +120 -0
  184. package/src/animation/demos/bouncy-switch.tsx +47 -0
  185. package/src/animation/demos/color-interpolation.tsx +73 -0
  186. package/src/animation/demos/cube.tsx +116 -0
  187. package/src/animation/demos/default-animate.tsx +129 -0
  188. package/src/animation/demos/drag-release.ts +118 -0
  189. package/src/animation/demos/enter.tsx +22 -0
  190. package/src/animation/demos/exit.tsx +79 -0
  191. package/src/animation/demos/flip-toggle.tsx +46 -0
  192. package/src/animation/demos/hold-to-confirm.tsx +317 -0
  193. package/src/animation/demos/html-content.tsx +41 -0
  194. package/src/animation/demos/interruptible-keyframes.tsx +62 -0
  195. package/src/animation/demos/keyframes.tsx +29 -0
  196. package/src/animation/demos/material-ripple.tsx +158 -0
  197. package/src/animation/demos/mixin-presence-list.tsx +121 -0
  198. package/src/animation/demos/mixin-reclaim.tsx +125 -0
  199. package/src/animation/demos/multi-state-badge.tsx +426 -0
  200. package/src/animation/demos/press.tsx +67 -0
  201. package/src/animation/demos/reordering.tsx +68 -0
  202. package/src/animation/demos/rolling-square.tsx +57 -0
  203. package/src/animation/demos/rotate.tsx +21 -0
  204. package/src/animation/demos/shared-layout.tsx +211 -0
  205. package/src/animation/demos/transition-options.tsx +24 -0
  206. package/src/animation/spring.ts +22 -0
  207. package/src/{components/breadcrumbs → breadcrumbs}/README.md +4 -4
  208. package/src/{components/breadcrumbs/breadcrumbs.tsx → breadcrumbs/index.tsx} +18 -18
  209. package/src/button/README.md +44 -0
  210. package/src/button/index.ts +168 -0
  211. package/src/checkbox/README.md +59 -0
  212. package/src/checkbox/index.ts +162 -0
  213. package/src/{components/combobox → combobox}/README.md +58 -9
  214. package/src/combobox/index.tsx +112 -0
  215. package/src/{components/combobox/combobox.tsx → combobox/primitives.tsx} +5 -91
  216. package/src/input/README.md +52 -0
  217. package/src/input/index.ts +147 -0
  218. package/src/{components/listbox → listbox}/README.md +9 -41
  219. package/src/{components/listbox/listbox.ts → listbox/index.ts} +2 -87
  220. package/src/menu/README.md +161 -0
  221. package/src/menu/index.tsx +354 -0
  222. package/src/{components/menu/menu.tsx → menu/primitives.tsx} +117 -359
  223. package/src/{components/popover → popover}/README.md +20 -39
  224. package/src/{components/popover/popover.ts → popover/index.ts} +16 -61
  225. package/src/{utils → popover}/scroll-lock.ts +0 -28
  226. package/src/radio/README.md +53 -0
  227. package/src/radio/index.ts +100 -0
  228. package/src/runtime/client-entries.ts +1 -5
  229. package/src/runtime/component.ts +3 -3
  230. package/src/runtime/demos/readme.demo.tsx +704 -0
  231. package/src/runtime/diff-dom.ts +270 -20
  232. package/src/runtime/frame.ts +218 -41
  233. package/src/runtime/jsx.ts +6 -10
  234. package/src/runtime/reconcile.ts +11 -5
  235. package/src/runtime/vdom.ts +3 -0
  236. package/src/{components/select → select}/README.md +29 -19
  237. package/src/select/index.tsx +159 -0
  238. package/src/{components/select/select.tsx → select/primitives.tsx} +11 -99
  239. package/src/server/stream.ts +10 -5
  240. package/src/shared/focus-styles.ts +2 -0
  241. package/src/shared/icons.tsx +62 -0
  242. package/src/shared/listbox-popover-styles.ts +146 -0
  243. package/src/shared/style-values.ts +165 -0
  244. package/src/style/style.ts +29 -10
  245. package/src/tabs/README.md +141 -0
  246. package/src/tabs/index.tsx +244 -0
  247. package/src/tabs/primitives.ts +365 -0
  248. package/src/toggle/README.md +56 -0
  249. package/src/toggle/index.tsx +134 -0
  250. package/src/toggle/primitives.ts +192 -0
  251. package/dist/components/accordion/accordion.d.ts +0 -92
  252. package/dist/components/accordion/accordion.js +0 -335
  253. package/dist/components/accordion/accordion.js.map +0 -1
  254. package/dist/components/accordion/demos/card.demo.d.ts +0 -6
  255. package/dist/components/accordion/demos/card.demo.js +0 -58
  256. package/dist/components/accordion/demos/card.demo.js.map +0 -1
  257. package/dist/components/accordion/demos/multiple.demo.d.ts +0 -6
  258. package/dist/components/accordion/demos/multiple.demo.js +0 -19
  259. package/dist/components/accordion/demos/multiple.demo.js.map +0 -1
  260. package/dist/components/accordion/demos/overview.demo.d.ts +0 -6
  261. package/dist/components/accordion/demos/overview.demo.js +0 -19
  262. package/dist/components/accordion/demos/overview.demo.js.map +0 -1
  263. package/dist/components/anchor/anchor.js.map +0 -1
  264. package/dist/components/breadcrumbs/breadcrumbs.js.map +0 -1
  265. package/dist/components/breadcrumbs/demos/basic.demo.d.ts +0 -5
  266. package/dist/components/breadcrumbs/demos/basic.demo.js +0 -14
  267. package/dist/components/breadcrumbs/demos/basic.demo.js.map +0 -1
  268. package/dist/components/breadcrumbs/demos/separator.demo.d.ts +0 -5
  269. package/dist/components/breadcrumbs/demos/separator.demo.js +0 -14
  270. package/dist/components/breadcrumbs/demos/separator.demo.js.map +0 -1
  271. package/dist/components/button/button.d.ts +0 -105
  272. package/dist/components/button/button.js +0 -207
  273. package/dist/components/button/button.js.map +0 -1
  274. package/dist/components/button/demos/aliases.demo.d.ts +0 -6
  275. package/dist/components/button/demos/aliases.demo.js +0 -18
  276. package/dist/components/button/demos/aliases.demo.js.map +0 -1
  277. package/dist/components/button/demos/basic.demo.d.ts +0 -6
  278. package/dist/components/button/demos/basic.demo.js +0 -19
  279. package/dist/components/button/demos/basic.demo.js.map +0 -1
  280. package/dist/components/button/demos/states.demo.d.ts +0 -6
  281. package/dist/components/button/demos/states.demo.js +0 -29
  282. package/dist/components/button/demos/states.demo.js.map +0 -1
  283. package/dist/components/combobox/combobox.js.map +0 -1
  284. package/dist/components/combobox/demos/overview.demo.d.ts +0 -6
  285. package/dist/components/combobox/demos/overview.demo.js +0 -153
  286. package/dist/components/combobox/demos/overview.demo.js.map +0 -1
  287. package/dist/components/glyph/glyph.d.ts +0 -14
  288. package/dist/components/glyph/glyph.js +0 -65
  289. package/dist/components/glyph/glyph.js.map +0 -1
  290. package/dist/components/listbox/demos/overview.demo.d.ts +0 -6
  291. package/dist/components/listbox/demos/overview.demo.js +0 -64
  292. package/dist/components/listbox/demos/overview.demo.js.map +0 -1
  293. package/dist/components/listbox/listbox.js.map +0 -1
  294. package/dist/components/menu/demos/bubbling.demo.d.ts +0 -5
  295. package/dist/components/menu/demos/bubbling.demo.js +0 -15
  296. package/dist/components/menu/demos/bubbling.demo.js.map +0 -1
  297. package/dist/components/menu/demos/overview.demo.d.ts +0 -6
  298. package/dist/components/menu/demos/overview.demo.js +0 -32
  299. package/dist/components/menu/demos/overview.demo.js.map +0 -1
  300. package/dist/components/menu/hover-aim.js.map +0 -1
  301. package/dist/components/menu/menu.js.map +0 -1
  302. package/dist/components/popover/demos/overview.demo.d.ts +0 -6
  303. package/dist/components/popover/demos/overview.demo.js +0 -64
  304. package/dist/components/popover/demos/overview.demo.js.map +0 -1
  305. package/dist/components/popover/popover.js.map +0 -1
  306. package/dist/components/select/demos/deconstructed.demo.d.ts +0 -6
  307. package/dist/components/select/demos/deconstructed.demo.js +0 -53
  308. package/dist/components/select/demos/deconstructed.demo.js.map +0 -1
  309. package/dist/components/select/demos/overview.demo.d.ts +0 -5
  310. package/dist/components/select/demos/overview.demo.js +0 -27
  311. package/dist/components/select/demos/overview.demo.js.map +0 -1
  312. package/dist/components/select/select.js.map +0 -1
  313. package/dist/components/separator/separator.d.ts +0 -2
  314. package/dist/components/separator/separator.js +0 -15
  315. package/dist/components/separator/separator.js.map +0 -1
  316. package/dist/components/tabs/tabs.d.ts +0 -78
  317. package/dist/components/tabs/tabs.js +0 -339
  318. package/dist/components/tabs/tabs.js.map +0 -1
  319. package/dist/interactions/keydown/keydown.js.map +0 -1
  320. package/dist/interactions/outside-click/outside-click-mixin.js.map +0 -1
  321. package/dist/interactions/typeahead/typeahead-mixin.js.map +0 -1
  322. package/dist/theme/contract.d.ts +0 -61
  323. package/dist/theme/contract.js +0 -131
  324. package/dist/theme/contract.js.map +0 -1
  325. package/dist/theme/glyph-contract.d.ts +0 -11
  326. package/dist/theme/glyph-contract.js +0 -34
  327. package/dist/theme/glyph-contract.js.map +0 -1
  328. package/dist/theme/presets/rmx-01/glyphs.d.ts +0 -2
  329. package/dist/theme/presets/rmx-01/glyphs.js +0 -252
  330. package/dist/theme/presets/rmx-01/glyphs.js.map +0 -1
  331. package/dist/theme/presets/rmx-01/index.d.ts +0 -4
  332. package/dist/theme/presets/rmx-01/index.js.map +0 -1
  333. package/dist/theme/runtime.d.ts +0 -2
  334. package/dist/theme/runtime.js +0 -84
  335. package/dist/theme/runtime.js.map +0 -1
  336. package/dist/theme/theme.d.ts +0 -6
  337. package/dist/theme/theme.js +0 -5
  338. package/dist/theme/theme.js.map +0 -1
  339. package/dist/utils/flash-attribute.js.map +0 -1
  340. package/dist/utils/scroll-lock.d.ts +0 -3
  341. package/dist/utils/scroll-lock.js.map +0 -1
  342. package/dist/utils/wait-for-css-transition.js.map +0 -1
  343. package/dist/utils/wait.js.map +0 -1
  344. package/src/components/accordion/accordion.tsx +0 -565
  345. package/src/components/accordion/demos/card.demo.tsx +0 -113
  346. package/src/components/accordion/demos/multiple.demo.tsx +0 -56
  347. package/src/components/accordion/demos/overview.demo.tsx +0 -56
  348. package/src/components/breadcrumbs/demos/basic.demo.tsx +0 -17
  349. package/src/components/breadcrumbs/demos/separator.demo.tsx +0 -18
  350. package/src/components/button/README.md +0 -44
  351. package/src/components/button/button.tsx +0 -286
  352. package/src/components/button/demos/aliases.demo.tsx +0 -27
  353. package/src/components/button/demos/basic.demo.tsx +0 -30
  354. package/src/components/button/demos/states.demo.tsx +0 -52
  355. package/src/components/combobox/demos/overview.demo.tsx +0 -199
  356. package/src/components/glyph/README.md +0 -72
  357. package/src/components/glyph/glyph.tsx +0 -110
  358. package/src/components/listbox/demos/overview.demo.tsx +0 -101
  359. package/src/components/menu/README.md +0 -96
  360. package/src/components/menu/demos/bubbling.demo.tsx +0 -34
  361. package/src/components/menu/demos/overview.demo.tsx +0 -76
  362. package/src/components/popover/demos/overview.demo.tsx +0 -143
  363. package/src/components/select/demos/deconstructed.demo.tsx +0 -95
  364. package/src/components/select/demos/overview.demo.tsx +0 -51
  365. package/src/components/separator/separator.ts +0 -19
  366. package/src/components/tabs/README.md +0 -105
  367. package/src/components/tabs/tabs.tsx +0 -504
  368. package/src/theme/README.md +0 -103
  369. package/src/theme/contract.ts +0 -215
  370. package/src/theme/glyph-contract.ts +0 -59
  371. package/src/theme/presets/rmx-01/glyphs.tsx +0 -308
  372. package/src/theme/presets/rmx-01/index.ts +0 -123
  373. package/src/theme/runtime.ts +0 -119
  374. package/src/theme/theme.ts +0 -15
  375. package/src/utils/scroll-lock/README.md +0 -33
  376. /package/dist/{components/breadcrumbs/breadcrumbs.d.ts → breadcrumbs/index.d.ts} +0 -0
  377. /package/dist/{utils → listbox}/flash-attribute.d.ts +0 -0
  378. /package/dist/{utils → listbox}/flash-attribute.js +0 -0
  379. /package/dist/{components/menu → menu}/hover-aim.d.ts +0 -0
  380. /package/dist/{components/menu → menu}/hover-aim.js +0 -0
  381. /package/dist/{interactions/outside-click/outside-click-mixin.d.ts → popover/outside-click.d.ts} +0 -0
  382. /package/dist/{interactions/keydown → select}/keydown.d.ts +0 -0
  383. /package/dist/{interactions/keydown → select}/keydown.js +0 -0
  384. /package/dist/{interactions/typeahead/typeahead-mixin.d.ts → shared/typeahead.d.ts} +0 -0
  385. /package/dist/{utils → shared}/wait-for-css-transition.d.ts +0 -0
  386. /package/dist/{utils → shared}/wait-for-css-transition.js +0 -0
  387. /package/dist/{utils → shared}/wait.d.ts +0 -0
  388. /package/dist/{utils → shared}/wait.js +0 -0
  389. /package/src/{utils → listbox}/flash-attribute.ts +0 -0
  390. /package/src/{components/menu → menu}/hover-aim.ts +0 -0
  391. /package/src/{interactions/outside-click/outside-click-mixin.ts → popover/outside-click.ts} +0 -0
  392. /package/src/{interactions/keydown → select}/keydown.ts +0 -0
  393. /package/src/{interactions/typeahead/typeahead-mixin.ts → shared/typeahead.ts} +0 -0
  394. /package/src/{utils → shared}/wait-for-css-transition.ts +0 -0
  395. /package/src/{utils → shared}/wait.ts +0 -0
@@ -0,0 +1,165 @@
1
+ type ComponentActionColors = {
2
+ readonly background: string
3
+ readonly backgroundHover: string
4
+ readonly backgroundActive: string
5
+ readonly foreground: string
6
+ readonly border: string
7
+ }
8
+
9
+ type ComponentStyleValues = {
10
+ readonly space: {
11
+ readonly none: string
12
+ readonly xs: string
13
+ readonly sm: string
14
+ readonly md: string
15
+ readonly lg: string
16
+ }
17
+ readonly radius: {
18
+ readonly md: string
19
+ readonly lg: string
20
+ readonly xl: string
21
+ readonly full: string
22
+ }
23
+ readonly fontFamily: {
24
+ readonly sans: string
25
+ }
26
+ readonly fontSize: {
27
+ readonly xs: string
28
+ readonly sm: string
29
+ readonly md: string
30
+ }
31
+ readonly lineHeight: {
32
+ readonly normal: string
33
+ readonly relaxed: string
34
+ }
35
+ readonly fontWeight: {
36
+ readonly normal: string
37
+ readonly medium: string
38
+ }
39
+ readonly control: {
40
+ readonly height: {
41
+ readonly sm: string
42
+ readonly md: string
43
+ readonly lg: string
44
+ }
45
+ }
46
+ readonly surface: {
47
+ readonly lvl0: string
48
+ readonly lvl1: string
49
+ readonly lvl2: string
50
+ readonly lvl3: string
51
+ readonly lvl4: string
52
+ }
53
+ readonly shadow: {
54
+ readonly xs: string
55
+ readonly sm: string
56
+ readonly md: string
57
+ }
58
+ readonly colors: {
59
+ readonly text: {
60
+ readonly primary: string
61
+ readonly secondary: string
62
+ readonly muted: string
63
+ }
64
+ readonly border: {
65
+ readonly subtle: string
66
+ readonly default: string
67
+ }
68
+ readonly focus: {
69
+ readonly ring: string
70
+ }
71
+ readonly action: {
72
+ readonly primary: ComponentActionColors
73
+ readonly secondary: ComponentActionColors
74
+ readonly danger: ComponentActionColors
75
+ }
76
+ }
77
+ }
78
+
79
+ export const componentStyleValues: ComponentStyleValues = {
80
+ space: {
81
+ none: '0px',
82
+ xs: '4px',
83
+ sm: '8px',
84
+ md: '12px',
85
+ lg: '16px',
86
+ },
87
+ radius: {
88
+ md: '8px',
89
+ lg: '12px',
90
+ xl: '16px',
91
+ full: '9999px',
92
+ },
93
+ fontSize: {
94
+ xs: '12px',
95
+ sm: '13px',
96
+ md: '14px',
97
+ },
98
+ fontFamily: {
99
+ sans: '"Inter", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
100
+ },
101
+ lineHeight: {
102
+ normal: '1.45',
103
+ relaxed: '1.65',
104
+ },
105
+ fontWeight: {
106
+ normal: '400',
107
+ medium: '500',
108
+ },
109
+ control: {
110
+ height: {
111
+ sm: '28px',
112
+ md: '32px',
113
+ lg: '36px',
114
+ },
115
+ },
116
+ surface: {
117
+ lvl0: '#ffffff',
118
+ lvl1: '#f8f8f8',
119
+ lvl2: '#f5f5f5',
120
+ lvl3: '#f3f3f3',
121
+ lvl4: '#efefef',
122
+ },
123
+ shadow: {
124
+ xs: '0 1px 1px rgb(0 0 0 / 0.05)',
125
+ sm: '0 1px 2px rgb(0 0 0 / 0.07)',
126
+ md: '0 6px 18px rgb(0 0 0 / 0.08)',
127
+ },
128
+ colors: {
129
+ text: {
130
+ primary: '#151515',
131
+ secondary: '#4f4f4f',
132
+ muted: '#6d6d6d',
133
+ },
134
+ border: {
135
+ subtle: '#e7e7e7',
136
+ default: '#d1d1d1',
137
+ },
138
+ focus: {
139
+ ring: '#1A72FF',
140
+ },
141
+ action: {
142
+ primary: {
143
+ background: '#1A72FF',
144
+ backgroundHover: '#1463e0',
145
+ backgroundActive: '#0f55c9',
146
+ foreground: 'rgb(255 255 255 / 0.92)',
147
+ border: '#1A72FF',
148
+ },
149
+ secondary: {
150
+ background: '#ffffff',
151
+ backgroundHover: '#fbfbfb',
152
+ backgroundActive: '#f3f3f3',
153
+ foreground: '#202020',
154
+ border: '#d1d1d1',
155
+ },
156
+ danger: {
157
+ background: '#FF3000',
158
+ backgroundHover: '#e12b00',
159
+ backgroundActive: '#c52600',
160
+ foreground: 'rgb(255 255 255 / 0.92)',
161
+ border: '#FF3000',
162
+ },
163
+ },
164
+ },
165
+ }
@@ -141,22 +141,15 @@ function styleToCss(styles: StyleObject, selector: string = ''): string {
141
141
  continue
142
142
  }
143
143
 
144
- // For nested selectors, keep them wholesale inside the base block
145
144
  // Allow nested selectors to be conditionally disabled.
146
145
  // e.g. { '&:hover': condition ? undefined : { ... } }
147
146
  let record = toRecord(value)
148
147
  if (!record) continue
149
148
 
150
- let nestedContent = ''
151
- for (let [prop, propValue] of Object.entries(record)) {
152
- if (propValue != null) {
153
- let normalizedValue = normalizeCssValue(prop, propValue)
154
- nestedContent += ` ${camelToKebab(prop)}: ${normalizedValue};\n`
155
- }
156
- }
157
- if (nestedContent) {
149
+ let nestedContent = nestedStyleBodyToCss(record, 4)
150
+ if (nestedContent.trim().length > 0) {
158
151
  // Preserve key verbatim (e.g., '&[aria-selected], &[rmx-focus]')
159
- nestedBlocks.push(` ${key} {\n${nestedContent} }`)
152
+ nestedBlocks.push(` ${key} {\n${nestedContent}\n }`)
160
153
  }
161
154
  } else {
162
155
  // Base declaration
@@ -189,6 +182,32 @@ function styleToCss(styles: StyleObject, selector: string = ''): string {
189
182
  return css
190
183
  }
191
184
 
185
+ function nestedStyleBodyToCss(styles: StyleObject, spaces: number): string {
186
+ // This renders content that is already inside a style rule. Nested selectors
187
+ // and nested at-rules can stay in that rule body; root at-rule placement is
188
+ // handled by styleToCss before entering a nested style body.
189
+ let pad = ' '.repeat(spaces)
190
+ let declarations: string[] = []
191
+ let nestedBlocks: string[] = []
192
+
193
+ for (let [key, value] of Object.entries(styles)) {
194
+ if (isComplexSelector(key)) {
195
+ let record = toRecord(value)
196
+ if (!record) continue
197
+
198
+ let nestedContent = nestedStyleBodyToCss(record, spaces + 2)
199
+ if (nestedContent.trim().length > 0) {
200
+ nestedBlocks.push(`${pad}${key} {\n${nestedContent}\n${pad}}`)
201
+ }
202
+ } else if (value != null) {
203
+ let normalizedValue = normalizeCssValue(key, value)
204
+ declarations.push(`${pad}${camelToKebab(key)}: ${normalizedValue};`)
205
+ }
206
+ }
207
+
208
+ return [...declarations, ...nestedBlocks].join('\n')
209
+ }
210
+
192
211
  function indent(text: string, spaces: number): string {
193
212
  let pad = ' '.repeat(spaces)
194
213
  return text
@@ -0,0 +1,141 @@
1
+ # tabs
2
+
3
+ `Tabs` renders a tab control with one active tab and matching panels. Use it when related views share the same page space and the owning component may either control the active tab or let the tabs context manage it.
4
+
5
+ ## Component Usage
6
+
7
+ ```tsx
8
+ import { Tabs, TabList, Tab, TabPanel } from 'remix/ui/tabs'
9
+
10
+ export function ProjectTabs() {
11
+ return (
12
+ <Tabs defaultActiveTab="overview">
13
+ <TabList aria-label="Project sections">
14
+ <Tab name="overview">Overview</Tab>
15
+ <Tab name="activity">Activity</Tab>
16
+ <Tab name="settings">Settings</Tab>
17
+ </TabList>
18
+
19
+ <TabPanel name="overview">Project summary.</TabPanel>
20
+ <TabPanel name="activity">Recent changes.</TabPanel>
21
+ <TabPanel name="settings">Project settings.</TabPanel>
22
+ </Tabs>
23
+ )
24
+ }
25
+ ```
26
+
27
+ Control the active tab when state should live in the owning component:
28
+
29
+ ```tsx
30
+ import type { Handle } from 'remix/ui'
31
+ import { Tabs, TabList, Tab, TabPanel } from 'remix/ui/tabs'
32
+
33
+ export function ControlledTabs(handle: Handle) {
34
+ let activeTab = 'overview'
35
+
36
+ return () => (
37
+ <Tabs
38
+ activeTab={activeTab}
39
+ onActiveTabChange={(nextActiveTab) => {
40
+ activeTab = nextActiveTab
41
+ void handle.update()
42
+ }}
43
+ >
44
+ <TabList aria-label="Project sections">
45
+ <Tab name="overview">Overview</Tab>
46
+ <Tab name="activity">Activity</Tab>
47
+ </TabList>
48
+
49
+ <TabPanel name="overview">Project summary.</TabPanel>
50
+ <TabPanel name="activity">Recent changes.</TabPanel>
51
+ </Tabs>
52
+ )
53
+ }
54
+ ```
55
+
56
+ Listen for bubbling `TabsChangeEvent` events with `onTabsChange` from `remix/ui/tabs/primitives`.
57
+
58
+ ```tsx
59
+ import { onTabsChange } from 'remix/ui/tabs/primitives'
60
+ import { Tabs, TabList, Tab, TabPanel } from 'remix/ui/tabs'
61
+
62
+ export function TrackedTabs() {
63
+ return (
64
+ <div
65
+ mix={[
66
+ onTabsChange((event) => {
67
+ console.log(event.previousActiveTab, event.activeTab)
68
+ }),
69
+ ]}
70
+ >
71
+ <Tabs defaultActiveTab="overview">
72
+ <TabList aria-label="Project sections">
73
+ <Tab name="overview">Overview</Tab>
74
+ <Tab name="activity">Activity</Tab>
75
+ </TabList>
76
+ <TabPanel name="overview">Project summary.</TabPanel>
77
+ <TabPanel name="activity">Recent changes.</TabPanel>
78
+ </Tabs>
79
+ </div>
80
+ )
81
+ }
82
+ ```
83
+
84
+ ## Primitive Usage
85
+
86
+ Use the lower-level primitives when app code owns the markup and styles:
87
+
88
+ ```tsx
89
+ import * as tabs from 'remix/ui/tabs/primitives'
90
+ import { listStyle, panelStyle, rootStyle, tabStyle } from './tabs.styles'
91
+
92
+ export function PrimitiveTabs() {
93
+ return (
94
+ <tabs.Context defaultActiveTab="overview">
95
+ <div mix={[rootStyle, tabs.root()]}>
96
+ <div mix={[listStyle, tabs.list()]} aria-label="Project sections">
97
+ <button mix={[tabStyle, tabs.tab({ name: 'overview' })]} type="button">
98
+ Overview
99
+ </button>
100
+ <button mix={[tabStyle, tabs.tab({ name: 'activity' })]} type="button">
101
+ Activity
102
+ </button>
103
+ </div>
104
+
105
+ <div mix={[panelStyle, tabs.panel({ name: 'overview' })]}>Project summary.</div>
106
+ <div mix={[panelStyle, tabs.panel({ name: 'activity' })]}>Recent changes.</div>
107
+ </div>
108
+ </tabs.Context>
109
+ )
110
+ }
111
+ ```
112
+
113
+ ## `remix/ui/tabs`
114
+
115
+ - `Tabs`: root component. Supports controlled `activeTab`, uncontrolled `defaultActiveTab`, `onActiveTabChange`, `disabled`, and `size: 'md' | 'lg'`.
116
+ - `TabList`: tablist wrapper that lays out the tabs in a track and applies the tablist primitive.
117
+ - `Tab`: button for one tab `name`. The active tab uses the toggle slider treatment and button-sized text. Pass `disabled` to prevent activation.
118
+ - `TabPanel`: panel for one tab `name`.
119
+ - `rootStyle`, `listStyle`, `tabStyle`, and `panelStyle`: flat style mixins used by the component markup.
120
+ - `onTabsChange` and `TabsChangeEvent`: re-exported primitive event helpers.
121
+ - `TabsProps`, `TabListProps`, `TabProps`, `TabPanelProps`, and `TabsSize`: public TypeScript types for the composed APIs.
122
+
123
+ ## `remix/ui/tabs/primitives`
124
+
125
+ - `Context`: lower-level provider for custom tabs composition.
126
+ - `root()`: wires the root element and bubbling change events.
127
+ - `list()`: wires the tablist role and disabled state.
128
+ - `tab({ name, disabled })`: wires a tab button with selected state, ids, keyboard activation, and pointer activation.
129
+ - `panel({ name })`: wires the matching tab panel id, hidden state, inert state, and label relationship.
130
+ - `onTabsChange(...)`: event mixin for the bubbling `TabsChangeEvent`.
131
+ - `TabsChangeEvent`: bubbling event with `activeTab` and `previousActiveTab`.
132
+ - `TabsContextProps`, `TabsContextValue`, `TabsRegisteredTab`, `TabsActivationDirection`, `TabsRootOptions`, `TabListOptions`, `TabOptions`, and `TabPanelOptions`: primitive prop and option types for custom composition.
133
+
134
+ ## Behavior Notes
135
+
136
+ - If neither `activeTab` nor `defaultActiveTab` is provided, the first enabled tab becomes active.
137
+ - Arrow keys activate the next or previous enabled tab. `Home` and `End` activate the first and last enabled tabs.
138
+ - `Enter`, `Space`, and pointer clicks activate the focused tab.
139
+ - Root `disabled` disables every tab. Tab `disabled` only disables that tab.
140
+ - Tabs and panels are linked with generated ids through `aria-controls`, `aria-labelledby`, and `aria-selected`.
141
+ - Inactive panels receive `hidden`, `inert`, and `data-state="inactive"`.
@@ -0,0 +1,244 @@
1
+ import {
2
+ css,
3
+ type CSSMixinDescriptor,
4
+ type Handle,
5
+ type Props,
6
+ type RemixNode,
7
+ } from '@remix-run/ui'
8
+ import * as tabs from '@remix-run/ui/tabs/primitives'
9
+
10
+ export { TabsChangeEvent, onTabsChange } from '@remix-run/ui/tabs/primitives'
11
+
12
+ export type TabsSize = 'md' | 'lg'
13
+
14
+ export interface TabsProps extends Omit<Props<'div'>, 'children'> {
15
+ activeTab?: string
16
+ children?: RemixNode
17
+ defaultActiveTab?: string
18
+ disabled?: boolean
19
+ onActiveTabChange?: (activeTab: string) => void
20
+ size?: TabsSize
21
+ }
22
+
23
+ export interface TabListProps extends Omit<Props<'div'>, 'children'> {
24
+ children?: RemixNode
25
+ }
26
+
27
+ export interface TabProps extends Omit<Props<'button'>, 'children' | 'type'> {
28
+ children?: RemixNode
29
+ disabled?: boolean
30
+ name: string
31
+ type?: 'button' | 'submit' | 'reset'
32
+ }
33
+
34
+ export interface TabPanelProps extends Omit<Props<'div'>, 'children'> {
35
+ children?: RemixNode
36
+ name: string
37
+ }
38
+
39
+ const tabSliderBackground =
40
+ 'linear-gradient(180deg, rgba(0, 0, 0, 0) 33%, rgba(0, 0, 0, 0.04) 100%), #FFFFFF'
41
+ const tabSliderShadow =
42
+ '0 0 0 0.5px rgba(0, 0, 0, 0.06), 0 1px 1px -0.5px rgba(0, 0, 0, 0.12), 0 2px 2px -1px rgba(0, 0, 0, 0.12), 0 4px 4px -2px rgba(0, 0, 0, 0.12), inset 0 0 2px 1px #FFFFFF'
43
+
44
+ const tabsRootCss: CSSMixinDescriptor = css({
45
+ '--rmx-tabs-height': '32px',
46
+ '--rmx-tabs-track-padding': '2px',
47
+ '--rmx-tabs-tab-padding-inline': '12px',
48
+ '--rmx-tabs-tab-shadow': '0 0 0 0 rgba(0, 0, 0, 0)',
49
+ '--rmx-tabs-tab-font-size': '12px',
50
+ '--rmx-tabs-tab-line-height': '17px',
51
+ '--rmx-tabs-gap': '12px',
52
+ boxSizing: 'border-box',
53
+ display: 'grid',
54
+ gap: 'var(--rmx-tabs-gap)',
55
+ minWidth: 0,
56
+ })
57
+
58
+ const tabsListCss: CSSMixinDescriptor = css({
59
+ boxSizing: 'border-box',
60
+ display: 'inline-flex',
61
+ alignItems: 'center',
62
+ gap: '2px',
63
+ width: 'max-content',
64
+ maxWidth: '100%',
65
+ minHeight: 'var(--rmx-tabs-height)',
66
+ padding: 'var(--rmx-tabs-track-padding)',
67
+ border: 0,
68
+ borderRadius: '9999px',
69
+ background: 'linear-gradient(180deg, rgba(0, 0, 0, 0.06) 0%, rgba(0, 0, 0, 0) 100%), #EBEBEB',
70
+ boxShadow:
71
+ 'inset 0 0 4px 1px rgba(0, 0, 0, 0.08), inset 0 1px 1px rgba(0, 0, 0, 0.02), inset 0 2px 2px rgba(0, 0, 0, 0.02)',
72
+ overflowX: 'auto',
73
+ scrollbarWidth: 'none',
74
+ '&::-webkit-scrollbar': {
75
+ display: 'none',
76
+ },
77
+ '&[aria-disabled="true"]': {
78
+ opacity: 0.55,
79
+ },
80
+ })
81
+
82
+ const tabsTabCss: CSSMixinDescriptor = css({
83
+ '--rmx-tabs-tab-focus-shadow':
84
+ '0 0 0 1px #3573F6, var(--rmx-tabs-tab-shadow), 0 0 0 4px rgba(53, 115, 246, 0.1), 0 6px 32px 4px rgba(53, 115, 246, 0.08), inset 0 0 8px 1px rgba(53, 115, 246, 0.05)',
85
+ appearance: 'none',
86
+ margin: 0,
87
+ boxSizing: 'border-box',
88
+ position: 'relative',
89
+ cursor: 'pointer',
90
+ display: 'inline-flex',
91
+ alignItems: 'center',
92
+ justifyContent: 'center',
93
+ flexDirection: 'row',
94
+ gap: '4px',
95
+ width: 'max-content',
96
+ maxWidth: '100%',
97
+ minWidth: 0,
98
+ height: 'calc(var(--rmx-tabs-height) - (var(--rmx-tabs-track-padding) * 2))',
99
+ minHeight: 'calc(var(--rmx-tabs-height) - (var(--rmx-tabs-track-padding) * 2))',
100
+ paddingBlock: 0,
101
+ paddingInline: 'var(--rmx-tabs-tab-padding-inline)',
102
+ border: 0,
103
+ borderRadius: '999px',
104
+ background: 'transparent',
105
+ boxShadow: 'var(--rmx-tabs-tab-shadow)',
106
+ color: '#707070',
107
+ fontFamily: '"Inter Variable", Inter, ui-sans-serif, system-ui, sans-serif',
108
+ fontStyle: 'normal',
109
+ fontWeight: 500,
110
+ fontSize: 'var(--rmx-tabs-tab-font-size)',
111
+ lineHeight: 'var(--rmx-tabs-tab-line-height)',
112
+ fontFeatureSettings: '"ss01" on, "cv01" on',
113
+ letterSpacing: 0,
114
+ textAlign: 'center',
115
+ textDecoration: 'none',
116
+ textShadow: 'none',
117
+ userSelect: 'none',
118
+ WebkitUserSelect: 'none',
119
+ verticalAlign: 'top',
120
+ whiteSpace: 'nowrap',
121
+ '&[data-state="inactive"]:hover:not(:disabled):not([aria-disabled="true"])': {
122
+ background: 'rgba(16, 16, 16, 0.05)',
123
+ color: '#101010',
124
+ },
125
+ '&[data-state="inactive"]:active:not(:disabled):not([aria-disabled="true"])': {
126
+ background: 'rgba(16, 16, 16, 0.08)',
127
+ },
128
+ '&[data-state="active"]': {
129
+ background: tabSliderBackground,
130
+ '--rmx-tabs-tab-shadow': tabSliderShadow,
131
+ color: '#101010',
132
+ textShadow: '0 1px 0 #FFFFFF',
133
+ },
134
+ '&[data-state="active"]:hover:not(:disabled):not([aria-disabled="true"])': {
135
+ background: tabSliderBackground,
136
+ },
137
+ '&[data-state="active"]:active:not(:disabled):not([aria-disabled="true"])': {
138
+ background: tabSliderBackground,
139
+ },
140
+ '&:disabled, &[aria-disabled="true"]': {
141
+ cursor: 'not-allowed',
142
+ opacity: 0.55,
143
+ },
144
+ '&:focus-visible': {
145
+ outline: 0,
146
+ boxShadow: 'var(--rmx-tabs-tab-focus-shadow)',
147
+ },
148
+ })
149
+
150
+ const tabsPanelCss: CSSMixinDescriptor = css({
151
+ minWidth: 0,
152
+ color: '#101010',
153
+ fontFamily: '"Inter Variable", Inter, ui-sans-serif, system-ui, sans-serif',
154
+ fontSize: '13px',
155
+ lineHeight: '20px',
156
+ letterSpacing: 0,
157
+ '&[hidden]': {
158
+ display: 'none',
159
+ },
160
+ })
161
+
162
+ const sizeStyles = {
163
+ md: css({}),
164
+ lg: css({
165
+ '--rmx-tabs-height': '36px',
166
+ '--rmx-tabs-tab-padding-inline': '14px',
167
+ '--rmx-tabs-tab-font-size': '13px',
168
+ '--rmx-tabs-tab-line-height': '20px',
169
+ '--rmx-tabs-gap': '14px',
170
+ }),
171
+ } as const satisfies Record<TabsSize, CSSMixinDescriptor>
172
+
173
+ export const rootStyle = tabsRootCss
174
+ export const listStyle = tabsListCss
175
+ export const tabStyle = tabsTabCss
176
+ export const panelStyle = tabsPanelCss
177
+
178
+ export function Tabs(handle: Handle<TabsProps>): () => RemixNode {
179
+ return () => {
180
+ let {
181
+ activeTab,
182
+ children,
183
+ defaultActiveTab,
184
+ disabled,
185
+ mix,
186
+ onActiveTabChange,
187
+ size = 'md',
188
+ ...divProps
189
+ } = handle.props
190
+
191
+ return (
192
+ <tabs.Context
193
+ activeTab={activeTab}
194
+ defaultActiveTab={defaultActiveTab}
195
+ disabled={disabled}
196
+ onActiveTabChange={onActiveTabChange}
197
+ >
198
+ <div {...divProps} mix={[rootStyle, sizeStyles[size], tabs.root(), mix]}>
199
+ {children}
200
+ </div>
201
+ </tabs.Context>
202
+ )
203
+ }
204
+ }
205
+
206
+ export function TabList(handle: Handle<TabListProps>): () => RemixNode {
207
+ return () => {
208
+ let { children, mix, ...divProps } = handle.props
209
+
210
+ return (
211
+ <div {...divProps} mix={[listStyle, tabs.list(), mix]}>
212
+ {children}
213
+ </div>
214
+ )
215
+ }
216
+ }
217
+
218
+ export function Tab(handle: Handle<TabProps>): () => RemixNode {
219
+ return () => {
220
+ let { children, disabled, mix, name, type, ...buttonProps } = handle.props
221
+
222
+ return (
223
+ <button
224
+ {...buttonProps}
225
+ mix={[tabStyle, tabs.tab({ disabled, name }), mix]}
226
+ type={type ?? 'button'}
227
+ >
228
+ {children}
229
+ </button>
230
+ )
231
+ }
232
+ }
233
+
234
+ export function TabPanel(handle: Handle<TabPanelProps>): () => RemixNode {
235
+ return () => {
236
+ let { children, mix, name, ...divProps } = handle.props
237
+
238
+ return (
239
+ <div {...divProps} mix={[panelStyle, tabs.panel({ name }), mix]}>
240
+ {children}
241
+ </div>
242
+ )
243
+ }
244
+ }