@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
@@ -129,6 +129,7 @@ export type FrameContext = {
129
129
  namedFrames: Map<string, FrameHandle>
130
130
  regionTailRef?: ChildNode | null
131
131
  regionParent?: ParentNode | null
132
+ signal?: AbortSignal
132
133
  }
133
134
 
134
135
  type FrameInit = {
@@ -153,6 +154,15 @@ export type Frame = {
153
154
  render: (content: InternalFrameContent, options?: RenderOptions) => Promise<void>
154
155
  ready: () => Promise<void>
155
156
  flush: () => void
157
+ clearPendingTemplateWatch: () => void
158
+ isDisplayingResolvedContent: () => boolean
159
+ startInheritedReload: (signal?: AbortSignal) => void
160
+ updateMarker: (marker: FrameMarkerData, options?: RenderOptions) => Promise<void>
161
+ renderMarkerContent: (
162
+ marker: FrameMarkerData,
163
+ content: InternalFrameContent,
164
+ options?: RenderOptions,
165
+ ) => Promise<void>
156
166
  dispose: () => void
157
167
  handle: FrameHandle
158
168
  }
@@ -161,15 +171,21 @@ type RenderOptions = {
161
171
  flushKind?: FlushKind
162
172
  initialHydrationTracker?: InitialHydrationTracker
163
173
  signal?: AbortSignal
174
+ contentStatus?: 'pending' | 'resolved'
164
175
  }
165
176
 
166
177
  export function createFrame(root: FrameRoot, init: FrameInit): Frame {
167
178
  let container = createContainer(root)
168
- let observers: MutationObserver[] = []
169
- let subscriptions: Array<() => void> = []
170
179
  let contentRoot: VirtualRoot | undefined
171
180
  let reloadController: AbortController | undefined
172
181
  let styleManager = init.styleManager ?? createStyleManager()
182
+ let currentMarker = init.marker
183
+ let displayedContentStatus: 'pending' | 'resolved' = init.marker?.status ?? 'resolved'
184
+ let pendingTemplateMarkerId: string | undefined
185
+ let pendingTemplateObserver: MutationObserver | undefined
186
+ let pendingTemplateUnsubscribe: (() => void) | undefined
187
+ let inheritedReloadPending = false
188
+ let inheritedReloadAbortUnsubscribe: (() => void) | undefined
173
189
 
174
190
  // Merge any rmx-data found in the current document once at startup.
175
191
  mergeRmxDataFromDocument(init.data, container.doc)
@@ -184,6 +200,7 @@ export function createFrame(root: FrameRoot, init: FrameInit): Frame {
184
200
  let controller = new AbortController()
185
201
  reloadController = controller
186
202
  frame.dispatchEvent(new Event('reloadStart'))
203
+ startSubFrameInheritedReloads(getContentNodes(), controller.signal)
187
204
  try {
188
205
  let content = await init.resolveFrame(frame.src, controller.signal, frameName)
189
206
  if (reloadController !== controller || controller.signal.aborted) return controller.signal
@@ -250,6 +267,7 @@ export function createFrame(root: FrameRoot, init: FrameInit): Frame {
250
267
 
251
268
  if (options?.signal?.aborted) return
252
269
  contentRoot.render(content)
270
+ displayedContentStatus = options?.contentStatus ?? 'resolved'
253
271
  return
254
272
  }
255
273
 
@@ -290,17 +308,20 @@ export function createFrame(root: FrameRoot, init: FrameInit): Frame {
290
308
  ...context,
291
309
  regionParent: container.doc.documentElement,
292
310
  regionTailRef: null,
311
+ signal: options?.signal,
293
312
  })
294
313
  diffNodes([container.doc.body], [parsed.body], {
295
314
  ...context,
296
315
  regionParent: container.doc.documentElement,
297
316
  regionTailRef: null,
317
+ signal: options?.signal,
298
318
  })
299
319
 
300
320
  let bodyContainer = createElementContainer(container.doc.body)
301
321
  if (options?.signal?.aborted) return
302
322
  scheduleHydrationInContainer(bodyContainer, context, options?.initialHydrationTracker)
303
- createSubFrames(bodyContainer.childNodes, context)
323
+ await createSubFrames(bodyContainer.childNodes, context, options)
324
+ displayedContentStatus = options?.contentStatus ?? 'resolved'
304
325
  return
305
326
  }
306
327
 
@@ -320,11 +341,13 @@ export function createFrame(root: FrameRoot, init: FrameInit): Frame {
320
341
  ...context,
321
342
  regionTailRef: container.regionTailRef,
322
343
  regionParent: container.regionParent,
344
+ signal: options?.signal,
323
345
  })
324
346
 
325
347
  if (options?.signal?.aborted) return
326
348
  scheduleHydrationInContainer(container, context, options?.initialHydrationTracker)
327
- createSubFrames(container.childNodes, context)
349
+ await createSubFrames(container.childNodes, context, options)
350
+ displayedContentStatus = options?.contentStatus ?? 'resolved'
328
351
  }
329
352
 
330
353
  function createFrameContentRoot(): VirtualRoot {
@@ -368,30 +391,11 @@ export function createFrame(root: FrameRoot, init: FrameInit): Frame {
368
391
  let initialHydrationTracker = createInitialHydrationTracker()
369
392
 
370
393
  context.styleManager.replaceServerStyles(collectFrameServerStyleTags(container))
371
- createSubFrames(container.childNodes, context)
394
+ await createSubFrames(container.childNodes, context)
372
395
  scheduleHydrationInContainer(container, context, initialHydrationTracker)
373
396
 
374
- if (init.marker?.status === 'pending') {
375
- let markerId = init.marker.id
376
- let early = consumeFrameTemplate(markerId) ?? getEarlyFrameContent(markerId)
377
- if (early) {
378
- await render(early, { initialHydrationTracker })
379
- } else {
380
- let observer = setupTemplateObserver()
381
- let unsubscribe = subscribeFrameTemplate(markerId, async (fragment) => {
382
- unsubscribe()
383
- await render(fragment)
384
- observer.disconnect()
385
- })
386
- subscriptions.push(unsubscribe)
387
- let buffered = consumeFrameTemplate(markerId)
388
- if (buffered) {
389
- unsubscribe()
390
- await render(buffered)
391
- observer.disconnect()
392
- }
393
- observers.push(observer)
394
- }
397
+ if (currentMarker?.status === 'pending') {
398
+ await watchPendingFrameTemplate(currentMarker, initialHydrationTracker)
395
399
  }
396
400
 
397
401
  initialHydrationTracker.finalize()
@@ -403,16 +407,7 @@ export function createFrame(root: FrameRoot, init: FrameInit): Frame {
403
407
  reloadController = undefined
404
408
  contentRoot?.dispose()
405
409
  contentRoot = undefined
406
-
407
- // Disconnect any MutationObservers waiting for templates.
408
- for (let observer of observers) {
409
- observer.disconnect()
410
- }
411
- observers.length = 0
412
- for (let unsubscribe of subscriptions) {
413
- unsubscribe()
414
- }
415
- subscriptions.length = 0
410
+ clearPendingFrameTemplateWatch()
416
411
 
417
412
  // Remove hydrated virtual roots in this frame's region.
418
413
  removeVirtualRoots(container.childNodes)
@@ -434,9 +429,173 @@ export function createFrame(root: FrameRoot, init: FrameInit): Frame {
434
429
  render,
435
430
  ready: () => readyPromise,
436
431
  flush: () => context.scheduler.dequeue(),
432
+ clearPendingTemplateWatch: clearPendingFrameTemplateWatch,
433
+ isDisplayingResolvedContent: () => displayedContentStatus === 'resolved',
434
+ startInheritedReload,
435
+ updateMarker,
436
+ renderMarkerContent,
437
437
  dispose,
438
438
  handle: frame,
439
439
  }
440
+
441
+ async function updateMarker(marker: FrameMarkerData, options?: RenderOptions): Promise<void> {
442
+ if (options?.signal?.aborted) return
443
+ let previousMarker = currentMarker
444
+ let isInheritedReload = previousMarker !== undefined && previousMarker.id !== marker.id
445
+ currentMarker = marker
446
+
447
+ if (isInheritedReload) {
448
+ startInheritedReload(options?.signal)
449
+ }
450
+
451
+ if (marker.status === 'pending') {
452
+ await watchPendingFrameTemplate(
453
+ marker,
454
+ options?.initialHydrationTracker,
455
+ options?.signal,
456
+ isInheritedReload
457
+ ? () => {
458
+ completeInheritedReload()
459
+ }
460
+ : undefined,
461
+ )
462
+ } else {
463
+ clearPendingFrameTemplateWatch()
464
+ if (isInheritedReload && !options?.signal?.aborted) {
465
+ completeInheritedReload()
466
+ }
467
+ }
468
+ }
469
+
470
+ async function renderMarkerContent(
471
+ marker: FrameMarkerData,
472
+ content: InternalFrameContent,
473
+ options?: RenderOptions,
474
+ ): Promise<void> {
475
+ if (options?.signal?.aborted) return
476
+ let previousMarker = currentMarker
477
+ let isInheritedReload = previousMarker !== undefined && previousMarker.id !== marker.id
478
+ currentMarker = marker
479
+
480
+ if (isInheritedReload) {
481
+ startInheritedReload(options?.signal)
482
+ }
483
+
484
+ clearPendingFrameTemplateWatch()
485
+ await render(content, { ...options, contentStatus: 'resolved' })
486
+
487
+ if (isInheritedReload && !options?.signal?.aborted) {
488
+ completeInheritedReload()
489
+ }
490
+ }
491
+
492
+ function startInheritedReload(signal?: AbortSignal): void {
493
+ if (signal?.aborted) return
494
+ if (!inheritedReloadPending) {
495
+ inheritedReloadPending = true
496
+ frame.dispatchEvent(new Event('reloadStart'))
497
+ startSubFrameInheritedReloads(getContentNodes(), signal)
498
+ }
499
+
500
+ inheritedReloadAbortUnsubscribe?.()
501
+ inheritedReloadAbortUnsubscribe = undefined
502
+ if (signal) {
503
+ let abort = () => completeInheritedReload()
504
+ signal.addEventListener('abort', abort, { once: true })
505
+ inheritedReloadAbortUnsubscribe = () => {
506
+ signal.removeEventListener('abort', abort)
507
+ }
508
+ }
509
+ }
510
+
511
+ function completeInheritedReload(): void {
512
+ if (!inheritedReloadPending) return
513
+ inheritedReloadPending = false
514
+ inheritedReloadAbortUnsubscribe?.()
515
+ inheritedReloadAbortUnsubscribe = undefined
516
+ frame.dispatchEvent(new Event('reloadComplete'))
517
+ }
518
+
519
+ function startSubFrameInheritedReloads(nodes: Node[], signal?: AbortSignal): void {
520
+ for (let i = 0; i < nodes.length; i++) {
521
+ if (signal?.aborted) break
522
+
523
+ let node = nodes[i]
524
+
525
+ if (isFrameStart(node)) {
526
+ let end = findEndMarker(node, isFrameStart, isFrameEnd)
527
+ context.frameInstances.get(node)?.startInheritedReload(signal)
528
+ i = nodes.indexOf(end)
529
+ continue
530
+ }
531
+
532
+ if (node.childNodes && node.childNodes.length > 0) {
533
+ startSubFrameInheritedReloads(Array.from(node.childNodes), signal)
534
+ }
535
+ }
536
+ }
537
+
538
+ function clearPendingFrameTemplateWatch(): void {
539
+ pendingTemplateUnsubscribe?.()
540
+ pendingTemplateUnsubscribe = undefined
541
+ pendingTemplateObserver?.disconnect()
542
+ pendingTemplateObserver = undefined
543
+ pendingTemplateMarkerId = undefined
544
+ }
545
+
546
+ async function watchPendingFrameTemplate(
547
+ marker: FrameMarkerData,
548
+ initialHydrationTracker?: InitialHydrationTracker,
549
+ signal?: AbortSignal,
550
+ onResolved?: () => void,
551
+ ): Promise<void> {
552
+ if (signal?.aborted) return
553
+ if (pendingTemplateMarkerId === marker.id) return
554
+
555
+ clearPendingFrameTemplateWatch()
556
+ pendingTemplateMarkerId = marker.id
557
+
558
+ let early = consumeFrameTemplate(marker.id) ?? getEarlyFrameContent(marker.id)
559
+ if (early) {
560
+ clearPendingFrameTemplateWatch()
561
+ await render(early, { initialHydrationTracker, signal, contentStatus: 'resolved' })
562
+ if (!signal?.aborted) onResolved?.()
563
+ return
564
+ }
565
+
566
+ if (signal?.aborted) {
567
+ clearPendingFrameTemplateWatch()
568
+ return
569
+ }
570
+
571
+ let observer = setupTemplateObserver()
572
+ pendingTemplateObserver = observer
573
+ let unsubscribe = subscribeFrameTemplate(marker.id, async (fragment) => {
574
+ if (signal?.aborted) return
575
+ if (pendingTemplateMarkerId !== marker.id) return
576
+ clearPendingFrameTemplateWatch()
577
+ await render(fragment, { signal, contentStatus: 'resolved' })
578
+ if (!signal?.aborted) onResolved?.()
579
+ })
580
+ pendingTemplateUnsubscribe = unsubscribe
581
+
582
+ signal?.addEventListener(
583
+ 'abort',
584
+ () => {
585
+ if (pendingTemplateMarkerId === marker.id) {
586
+ clearPendingFrameTemplateWatch()
587
+ }
588
+ },
589
+ { once: true },
590
+ )
591
+
592
+ let buffered = consumeFrameTemplate(marker.id)
593
+ if (buffered) {
594
+ clearPendingFrameTemplateWatch()
595
+ await render(buffered, { initialHydrationTracker, signal, contentStatus: 'resolved' })
596
+ if (!signal?.aborted) onResolved?.()
597
+ }
598
+ }
440
599
  }
441
600
 
442
601
  export function createFrameRuntime(init: {
@@ -752,16 +911,32 @@ function hydrateRegion(
752
911
  root.render(vElement)
753
912
  }
754
913
 
755
- function createSubFrames(nodes: Node[], context: FrameContext) {
914
+ async function createSubFrames(
915
+ nodes: Node[],
916
+ context: FrameContext,
917
+ options?: RenderOptions,
918
+ ): Promise<void> {
919
+ let tasks: Promise<void>[] = []
920
+
756
921
  for (let i = 0; i < nodes.length; i++) {
922
+ if (options?.signal?.aborted) break
923
+
757
924
  let node = nodes[i]
758
925
 
759
926
  if (isFrameStart(node)) {
760
927
  let end = findEndMarker(node, isFrameStart, isFrameEnd)
928
+ let existingFrame = context.frameInstances.get(node)
929
+ let id = getFrameId(node)
930
+ let marker = context.data.f?.[id]
761
931
 
762
- if (!context.frameInstances.has(node)) {
763
- let id = getFrameId(node)
764
- let marker = context.data.f?.[id]
932
+ if (existingFrame) {
933
+ if (marker) {
934
+ let frameMarker: FrameMarkerData = { ...marker, id }
935
+ tasks.push(existingFrame.updateMarker(frameMarker, options))
936
+ } else {
937
+ existingFrame.clearPendingTemplateWatch()
938
+ }
939
+ } else {
765
940
  if (marker) {
766
941
  let frameMarker: FrameMarkerData = { ...marker, id }
767
942
  let subFrame = createFrame([node, end], {
@@ -788,9 +963,11 @@ function createSubFrames(nodes: Node[], context: FrameContext) {
788
963
  }
789
964
 
790
965
  if (node.childNodes && node.childNodes.length > 0) {
791
- createSubFrames(Array.from(node.childNodes), context)
966
+ tasks.push(createSubFrames(Array.from(node.childNodes), context, options))
792
967
  }
793
968
  }
969
+
970
+ await Promise.all(tasks)
794
971
  }
795
972
 
796
973
  function isHydrationMarkerLive(marker: HydrationMarker, context: FrameContext): boolean {
@@ -77,10 +77,6 @@ type MixinElementType = ((
77
77
  __rmxMixinElementType: string
78
78
  }
79
79
 
80
- type MergeComponentProps<handleProps, renderProps> = [handleProps] extends [Record<string, never>]
81
- ? renderProps
82
- : handleProps & renderProps
83
-
84
80
  /**
85
81
  * Get the props for a specific element type.
86
82
  *
@@ -120,7 +116,7 @@ declare global {
120
116
  // host elements
121
117
  | keyof IntrinsicElements
122
118
  // Factory component
123
- | ((handle: Handle<any, any>) => RenderFn<any>)
119
+ | ((handle: Handle<any, any>) => RenderFn)
124
120
  // Mixin element used internally by mixin render callbacks
125
121
  | MixinElementType
126
122
 
@@ -134,11 +130,11 @@ declare global {
134
130
 
135
131
  type LibraryManagedAttributes<component, props> = component extends MixinElementType
136
132
  ? ExpandMixProp<Parameters<ReturnType<component>>[0]>
137
- : component extends (handle: Handle<infer P, any>) => RenderFn<infer R>
138
- ? // It's a ComponentFactory - infer props from the handle
139
- ExpandMixProp<MergeComponentProps<P, R>>
140
- : component extends () => RenderFn<infer P>
141
- ? ExpandMixProp<P>
133
+ : component extends () => RenderFn
134
+ ? ExpandMixProp<Record<string, never>>
135
+ : component extends (handle: Handle<infer P, any>) => RenderFn
136
+ ? // It's a ComponentFactory - infer props from the handle
137
+ ExpandMixProp<P>
142
138
  : // Otherwise use props as-is (simple function component)
143
139
  ExpandMixProp<props>
144
140
 
@@ -340,6 +340,10 @@ function enqueueMixinBindingUpdate(
340
340
  let prevProps = getHostProps(node)
341
341
  let nextProps = resolveNodeMixProps(node, this.frame, this.scheduler, state)
342
342
  patchHostProps(prevProps, nextProps, this.node)
343
+ if (node._controlledState || shouldTrackControlledReflection(nextProps)) {
344
+ ensureControlledReflection(node, this.scheduler)
345
+ syncControlledReflection(node, nextProps)
346
+ }
343
347
 
344
348
  dispatchMixinCommit(state)
345
349
  done(state ? getMixinRuntimeSignal(state) : AbortSignal.abort())
@@ -700,10 +704,12 @@ function insert(
700
704
  cursor = null
701
705
  }
702
706
 
703
- cursor =
704
- node.type === Frame
705
- ? skipCommentsExceptFrameStart(cursor ?? null)
706
- : skipComments(cursor ?? null)
707
+ // Preserve frame-start markers for non-Frame nodes too, so a following <Frame>
708
+ // (e.g. the first child of a bare Fragment at a clientEntry boundary) can still
709
+ // claim its rmx:f marker during hydration instead of being re-inserted fresh.
710
+ // A rmx:f marker always belongs to a <Frame>, so no non-Frame node should
711
+ // consume one.
712
+ cursor = skipCommentsExceptFrameStart(cursor ?? null)
707
713
 
708
714
  // Also check after skipComments in case we skipped past the anchor
709
715
  if (cursor && anchor && cursor === anchor) {
@@ -1097,7 +1103,7 @@ function resolveClientFrame(node: VNode, runtime: FrameRuntime): void {
1097
1103
  let resolveController = new AbortController()
1098
1104
  node._frameResolveController = resolveController
1099
1105
 
1100
- Promise.resolve(runtime.resolveFrame(frameSrc, resolveController.signal))
1106
+ Promise.resolve(runtime.resolveFrame(frameSrc, resolveController.signal, getFrameName(node)))
1101
1107
  .then(async (content) => {
1102
1108
  if (node._frameResolveToken !== token || resolveController.signal.aborted) return
1103
1109
  node._frameFallbackRoot?.dispose()
@@ -172,6 +172,9 @@ export function createRangeRoot(
172
172
  export function createRoot(container: HTMLElement, options: VirtualRootOptions = {}): VirtualRoot {
173
173
  let vroot: VNode | null = null
174
174
  let styles = options.styleManager ?? defaultStyleManager
175
+ if (container.innerHTML.trim() !== '') {
176
+ styles.replaceServerStyles(container)
177
+ }
175
178
  let hydrationCursor = container.innerHTML.trim() !== '' ? container.firstChild : undefined
176
179
 
177
180
  let eventTarget = new TypedEventTarget<VirtualRootEventMap>()
@@ -2,10 +2,11 @@
2
2
 
3
3
  `Select` is a button-triggered popup value picker backed by `listbox` and `popover`. Use it when the user should choose one stable string value from a finite set.
4
4
 
5
- ## Usage
5
+ ## Component Usage
6
6
 
7
7
  ```tsx
8
- import { Option, Select, onSelectChange } from 'remix/ui/select'
8
+ import { Option, Select } from 'remix/ui/select'
9
+ import { onSelectChange } from 'remix/ui/select/primitives'
9
10
 
10
11
  export function FrameworkSelect() {
11
12
  return (
@@ -44,34 +45,34 @@ Use `textValue` when closed-trigger typeahead should match a different string fr
44
45
  </Select>
45
46
  ```
46
47
 
48
+ ## Primitive Usage
49
+
47
50
  Use the lower-level primitives when the trigger or popup structure needs to be owned by another component. Keep the same provider, trigger, popover, list, option, and hidden-input relationship.
48
51
 
49
52
  ```tsx
50
53
  import type { Handle } from 'remix/ui'
51
- import * as button from 'remix/ui/button'
52
- import * as listbox from 'remix/ui/listbox'
53
54
  import * as popover from 'remix/ui/popover'
54
- import * as select from 'remix/ui/select'
55
+ import { triggerStyle } from 'remix/ui/select'
56
+ import * as select from 'remix/ui/select/primitives'
57
+ import { listStyle, optionStyle, surfaceStyle } from './select.styles'
55
58
 
56
59
  function SelectValue(handle: Handle) {
57
60
  let context = handle.context.get(select.Context)
58
61
 
59
- return () => <span mix={button.labelStyle}>{context.displayedLabel}</span>
62
+ return () => <span>{context.displayedLabel}</span>
60
63
  }
61
64
 
62
65
  function IssueTypeSelect() {
63
66
  return () => (
64
- <select.Context defaultLabel="Select a type" name="issueType">
65
- <button type="button" mix={[button.baseStyle, select.triggerStyle, select.trigger()]}>
67
+ <select.Context defaultLabel="Select a type" labelSwapDelayMs={100} name="issueType">
68
+ <button type="button" mix={[triggerStyle, select.trigger()]}>
66
69
  <SelectValue />
67
70
  </button>
68
71
  <popover.Context>
69
- <div mix={[popover.surfaceStyle, select.popover()]}>
70
- <div mix={[popover.contentStyle, listbox.listStyle, select.list()]}>
71
- <div mix={[listbox.optionStyle, select.option({ label: 'Bug', value: 'bug' })]}>
72
- Bug
73
- </div>
74
- <div mix={[listbox.optionStyle, select.option({ label: 'Feature', value: 'feature' })]}>
72
+ <div mix={[surfaceStyle, select.popover()]}>
73
+ <div mix={[listStyle, select.list()]}>
74
+ <div mix={[optionStyle, select.option({ label: 'Bug', value: 'bug' })]}>Bug</div>
75
+ <div mix={[optionStyle, select.option({ label: 'Feature', value: 'feature' })]}>
75
76
  Feature
76
77
  </div>
77
78
  </div>
@@ -83,15 +84,24 @@ function IssueTypeSelect() {
83
84
  }
84
85
  ```
85
86
 
86
- ## `select.*`
87
+ ## `remix/ui/select`
87
88
 
88
89
  - `Select`: composed trigger, popover, listbox, option list, and optional hidden input for form participation. Accepts `defaultLabel`, `defaultValue`, `disabled`, `name`, and button props.
89
- - `Option`: option wrapper that renders the standard check glyph and label slot. Accepts `label`, `value`, optional `disabled`, and optional `textValue`.
90
+ - `Option`: option component that renders the standard check indicator and label slot. Accepts `label`, `value`, optional `disabled`, and optional `textValue`.
91
+ - `triggerStyle`: standard select trigger style for custom trigger composition.
92
+ - `SelectProps` and `SelectOptionProps`: public TypeScript props for the composed APIs.
93
+
94
+ ## `remix/ui/select/primitives`
95
+
96
+ - `Context`: lower-level provider for custom composition. Accepts `defaultLabel`, `defaultValue`, `disabled`, `name`, and primitive-only `labelSwapDelayMs`; the label-swap delay defaults to `75` milliseconds.
97
+ - `trigger()`: wires the trigger button, open behavior, closed-trigger typeahead, and trigger ARIA attributes.
98
+ - `popover()`: wires the popover surface and keeps its min-width synced to the trigger before open.
99
+ - `list()`: wires the listbox root used inside the popover.
100
+ - `option(...)`: registers one selectable option. Accepts `label`, `value`, optional `disabled`, and optional `textValue`.
101
+ - `hiddenInput()`: mirrors the selected value into a hidden input for form participation.
90
102
  - `onSelectChange(...)`: event mixin for the bubbling `SelectChangeEvent`.
91
- - `Context`, `trigger()`, `popover()`, `list()`, `option(...)`, and `hiddenInput()`: lower-level composition primitives.
92
- - `triggerStyle`: standard select trigger style.
93
103
  - `SelectChangeEvent`: event with `value`, `label`, and `optionId`.
94
- - `SelectProps`, `SelectContextProps`, and `SelectOptionProps`: public TypeScript props for the composed and lower-level APIs.
104
+ - `SelectContextProps`, `SelectProps`, and `SelectOptionProps`: primitive prop types for custom composition.
95
105
 
96
106
  ## Behavior Notes
97
107