@oxy.so/bloom 4.5.0 → 4.6.1

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 (621) hide show
  1. package/README.md +1 -1
  2. package/docs/adoption-matrix.mdx +12 -12
  3. package/docs/code.mdx +12 -0
  4. package/docs/context-menu.mdx +2 -0
  5. package/docs/dropdown-menu.mdx +21 -0
  6. package/docs/icons.mdx +2 -2
  7. package/docs/menubar.mdx +6 -2
  8. package/docs/popover.mdx +4 -2
  9. package/docs/segmented-control.mdx +12 -0
  10. package/docs/select.mdx +19 -0
  11. package/docs/tabs.mdx +12 -0
  12. package/lib/commonjs/agent-chat/index.web.js.map +1 -1
  13. package/lib/commonjs/ai-chat/index.web.js.map +1 -1
  14. package/lib/commonjs/alert-dialog/index.web.js +10 -1
  15. package/lib/commonjs/alert-dialog/index.web.js.map +1 -1
  16. package/lib/commonjs/avatar-group/index.web.js.map +1 -1
  17. package/lib/commonjs/bottom-sheet/index.web.js.map +1 -1
  18. package/lib/commonjs/code/index.js +13 -0
  19. package/lib/commonjs/code/index.js.map +1 -1
  20. package/lib/commonjs/command/index.web.js +5 -0
  21. package/lib/commonjs/command/index.web.js.map +1 -1
  22. package/lib/commonjs/composer-loader/ComposerLoader.web.js +9 -0
  23. package/lib/commonjs/composer-loader/ComposerLoader.web.js.map +1 -1
  24. package/lib/commonjs/composer-loader/index.web.js.map +1 -1
  25. package/lib/commonjs/composer-panel/index.web.js.map +1 -1
  26. package/lib/commonjs/connection-dots/index.web.js.map +1 -1
  27. package/lib/commonjs/connection-status/index.web.js.map +1 -1
  28. package/lib/commonjs/content-panel/index.web.js.map +1 -1
  29. package/lib/commonjs/context-menu/ContextMenu.web.js +22 -4
  30. package/lib/commonjs/context-menu/ContextMenu.web.js.map +1 -1
  31. package/lib/commonjs/context-menu/context.js.map +1 -1
  32. package/lib/commonjs/context-menu/index.web.js.map +1 -1
  33. package/lib/commonjs/dialog/Dialog.web.js +14 -0
  34. package/lib/commonjs/dialog/Dialog.web.js.map +1 -1
  35. package/lib/commonjs/dialog/index.web.js.map +1 -1
  36. package/lib/commonjs/dropdown-menu/DropdownMenu.web.js +22 -2
  37. package/lib/commonjs/dropdown-menu/DropdownMenu.web.js.map +1 -1
  38. package/lib/commonjs/dropdown-menu/index.web.js.map +1 -1
  39. package/lib/commonjs/floating/FloatingPanel.js +42 -33
  40. package/lib/commonjs/floating/FloatingPanel.js.map +1 -1
  41. package/lib/commonjs/floating/escape-stack.js +90 -0
  42. package/lib/commonjs/floating/escape-stack.js.map +1 -0
  43. package/lib/commonjs/floating/menu-keyboard.js +238 -0
  44. package/lib/commonjs/floating/menu-keyboard.js.map +1 -0
  45. package/lib/commonjs/floating/menu-sub-flyout.js +28 -16
  46. package/lib/commonjs/floating/menu-sub-flyout.js.map +1 -1
  47. package/lib/commonjs/fonts/index.web.js.map +1 -1
  48. package/lib/commonjs/frosted-icon-button/FrostedIconButton.web.js +10 -0
  49. package/lib/commonjs/frosted-icon-button/FrostedIconButton.web.js.map +1 -1
  50. package/lib/commonjs/frosted-icon-button/index.web.js.map +1 -1
  51. package/lib/commonjs/hooks/roving-focus.js +192 -0
  52. package/lib/commonjs/hooks/roving-focus.js.map +1 -0
  53. package/lib/commonjs/hover-card/index.web.js.map +1 -1
  54. package/lib/commonjs/icons/remix/RiBookReadLine.js +12 -0
  55. package/lib/commonjs/icons/remix/RiBookReadLine.js.map +1 -0
  56. package/lib/commonjs/icons/remix/RiBugLine.js +12 -0
  57. package/lib/commonjs/icons/remix/RiBugLine.js.map +1 -0
  58. package/lib/commonjs/icons/remix/RiChat1Line.js +12 -0
  59. package/lib/commonjs/icons/remix/RiChat1Line.js.map +1 -0
  60. package/lib/commonjs/icons/remix/RiCloudLine.js +12 -0
  61. package/lib/commonjs/icons/remix/RiCloudLine.js.map +1 -0
  62. package/lib/commonjs/icons/remix/RiCodeLine.js +12 -0
  63. package/lib/commonjs/icons/remix/RiCodeLine.js.map +1 -0
  64. package/lib/commonjs/icons/remix/RiCpuLine.js +12 -0
  65. package/lib/commonjs/icons/remix/RiCpuLine.js.map +1 -0
  66. package/lib/commonjs/icons/remix/RiFloodLine.js +12 -0
  67. package/lib/commonjs/icons/remix/RiFloodLine.js.map +1 -0
  68. package/lib/commonjs/icons/remix/RiLockUnlockLine.js +12 -0
  69. package/lib/commonjs/icons/remix/RiLockUnlockLine.js.map +1 -0
  70. package/lib/commonjs/icons/remix/RiMoneyDollarCircleLine.js +12 -0
  71. package/lib/commonjs/icons/remix/RiMoneyDollarCircleLine.js.map +1 -0
  72. package/lib/commonjs/icons/remix/RiPlayCircleLine.js +12 -0
  73. package/lib/commonjs/icons/remix/RiPlayCircleLine.js.map +1 -0
  74. package/lib/commonjs/icons/remix/RiRocket2Line.js +12 -0
  75. package/lib/commonjs/icons/remix/RiRocket2Line.js.map +1 -0
  76. package/lib/commonjs/icons/remix/RiServerLine.js +12 -0
  77. package/lib/commonjs/icons/remix/RiServerLine.js.map +1 -0
  78. package/lib/commonjs/icons/remix/RiShareBoxLine.js +12 -0
  79. package/lib/commonjs/icons/remix/RiShareBoxLine.js.map +1 -0
  80. package/lib/commonjs/icons/remix/RiTv2Line.js +12 -0
  81. package/lib/commonjs/icons/remix/RiTv2Line.js.map +1 -0
  82. package/lib/commonjs/icons/remix/index.js +98 -0
  83. package/lib/commonjs/icons/remix/index.js.map +1 -1
  84. package/lib/commonjs/list/index.web.js.map +1 -1
  85. package/lib/commonjs/loading/Loading.js +21 -157
  86. package/lib/commonjs/loading/Loading.js.map +1 -1
  87. package/lib/commonjs/loading/Loading.web.js +23 -157
  88. package/lib/commonjs/loading/Loading.web.js.map +1 -1
  89. package/lib/commonjs/loading/LoadingBase.js +202 -0
  90. package/lib/commonjs/loading/LoadingBase.js.map +1 -0
  91. package/lib/commonjs/loading/index.web.js.map +1 -1
  92. package/lib/commonjs/media-flight/index.web.js.map +1 -1
  93. package/lib/commonjs/menubar/Menubar.js +31 -123
  94. package/lib/commonjs/menubar/Menubar.js.map +1 -1
  95. package/lib/commonjs/menubar/Menubar.web.js +33 -114
  96. package/lib/commonjs/menubar/Menubar.web.js.map +1 -1
  97. package/lib/commonjs/menubar/MenubarBase.js +154 -0
  98. package/lib/commonjs/menubar/MenubarBase.js.map +1 -0
  99. package/lib/commonjs/menubar/index.web.js.map +1 -1
  100. package/lib/commonjs/popover/index.web.js.map +1 -1
  101. package/lib/commonjs/popover/parts.js +69 -11
  102. package/lib/commonjs/popover/parts.js.map +1 -1
  103. package/lib/commonjs/popover/surface.js +39 -13
  104. package/lib/commonjs/popover/surface.js.map +1 -1
  105. package/lib/commonjs/portal/index.web.js.map +1 -1
  106. package/lib/commonjs/progressive-blur/index.web.js.map +1 -1
  107. package/lib/commonjs/scroll/index.web.js.map +1 -1
  108. package/lib/commonjs/segmented-control/SegmentedControl.js +36 -1
  109. package/lib/commonjs/segmented-control/SegmentedControl.js.map +1 -1
  110. package/lib/commonjs/select/Select.js +6 -81
  111. package/lib/commonjs/select/Select.js.map +1 -1
  112. package/lib/commonjs/select/Select.web.js +147 -85
  113. package/lib/commonjs/select/Select.web.js.map +1 -1
  114. package/lib/commonjs/select/index.js +4 -4
  115. package/lib/commonjs/select/index.js.map +1 -1
  116. package/lib/commonjs/select/index.web.js +4 -4
  117. package/lib/commonjs/select/index.web.js.map +1 -1
  118. package/lib/commonjs/select/shared.js +110 -5
  119. package/lib/commonjs/select/shared.js.map +1 -1
  120. package/lib/commonjs/sidebar/SidebarTeamMenu.js +1 -1
  121. package/lib/commonjs/sidebar/SidebarTeamMenu.js.map +1 -1
  122. package/lib/commonjs/sidebar/SidebarUserMenu.js +1 -1
  123. package/lib/commonjs/sidebar/SidebarUserMenu.js.map +1 -1
  124. package/lib/commonjs/sidebar/parts.js +9 -9
  125. package/lib/commonjs/sidebar/parts.js.map +1 -1
  126. package/lib/commonjs/surfaces/SurfaceHost.js +6 -0
  127. package/lib/commonjs/surfaces/SurfaceHost.js.map +1 -1
  128. package/lib/commonjs/surfaces/index.web.js +14 -4
  129. package/lib/commonjs/surfaces/index.web.js.map +1 -1
  130. package/lib/commonjs/tab-bar/index.web.js +13 -10
  131. package/lib/commonjs/tab-bar/index.web.js.map +1 -1
  132. package/lib/commonjs/tabs/Tabs.js +49 -2
  133. package/lib/commonjs/tabs/Tabs.js.map +1 -1
  134. package/lib/commonjs/theme/color-scope/index.web.js.map +1 -1
  135. package/lib/commonjs/theme/persistence.js +12 -1
  136. package/lib/commonjs/theme/persistence.js.map +1 -1
  137. package/lib/commonjs/theme/seed-scope/index.web.js.map +1 -1
  138. package/lib/commonjs/tooltip/index.web.js.map +1 -1
  139. package/lib/module/agent-chat/index.web.js +5 -3
  140. package/lib/module/agent-chat/index.web.js.map +1 -1
  141. package/lib/module/ai-chat/index.web.js +5 -2
  142. package/lib/module/ai-chat/index.web.js.map +1 -1
  143. package/lib/module/alert-dialog/index.web.js +10 -1
  144. package/lib/module/alert-dialog/index.web.js.map +1 -1
  145. package/lib/module/avatar-group/index.web.js +5 -0
  146. package/lib/module/avatar-group/index.web.js.map +1 -1
  147. package/lib/module/bottom-sheet/index.web.js +5 -0
  148. package/lib/module/bottom-sheet/index.web.js.map +1 -1
  149. package/lib/module/code/index.js +1 -0
  150. package/lib/module/code/index.js.map +1 -1
  151. package/lib/module/command/index.web.js +5 -0
  152. package/lib/module/command/index.web.js.map +1 -1
  153. package/lib/module/composer-loader/ComposerLoader.web.js +8 -0
  154. package/lib/module/composer-loader/ComposerLoader.web.js.map +1 -1
  155. package/lib/module/composer-loader/index.web.js +5 -2
  156. package/lib/module/composer-loader/index.web.js.map +1 -1
  157. package/lib/module/composer-panel/index.web.js +5 -3
  158. package/lib/module/composer-panel/index.web.js.map +1 -1
  159. package/lib/module/connection-dots/index.web.js +5 -0
  160. package/lib/module/connection-dots/index.web.js.map +1 -1
  161. package/lib/module/connection-status/index.web.js +5 -0
  162. package/lib/module/connection-status/index.web.js.map +1 -1
  163. package/lib/module/content-panel/index.web.js +5 -0
  164. package/lib/module/content-panel/index.web.js.map +1 -1
  165. package/lib/module/context-menu/ContextMenu.web.js +22 -4
  166. package/lib/module/context-menu/ContextMenu.web.js.map +1 -1
  167. package/lib/module/context-menu/context.js.map +1 -1
  168. package/lib/module/context-menu/index.web.js +5 -0
  169. package/lib/module/context-menu/index.web.js.map +1 -1
  170. package/lib/module/dialog/Dialog.web.js +13 -0
  171. package/lib/module/dialog/Dialog.web.js.map +1 -1
  172. package/lib/module/dialog/index.web.js +7 -11
  173. package/lib/module/dialog/index.web.js.map +1 -1
  174. package/lib/module/dropdown-menu/DropdownMenu.web.js +23 -3
  175. package/lib/module/dropdown-menu/DropdownMenu.web.js.map +1 -1
  176. package/lib/module/dropdown-menu/index.web.js +5 -0
  177. package/lib/module/dropdown-menu/index.web.js.map +1 -1
  178. package/lib/module/floating/FloatingPanel.js +42 -33
  179. package/lib/module/floating/FloatingPanel.js.map +1 -1
  180. package/lib/module/floating/escape-stack.js +85 -0
  181. package/lib/module/floating/escape-stack.js.map +1 -0
  182. package/lib/module/floating/menu-keyboard.js +227 -0
  183. package/lib/module/floating/menu-keyboard.js.map +1 -0
  184. package/lib/module/floating/menu-sub-flyout.js +28 -16
  185. package/lib/module/floating/menu-sub-flyout.js.map +1 -1
  186. package/lib/module/fonts/index.web.js +5 -20
  187. package/lib/module/fonts/index.web.js.map +1 -1
  188. package/lib/module/frosted-icon-button/FrostedIconButton.web.js +9 -0
  189. package/lib/module/frosted-icon-button/FrostedIconButton.web.js.map +1 -1
  190. package/lib/module/frosted-icon-button/index.web.js +5 -7
  191. package/lib/module/frosted-icon-button/index.web.js.map +1 -1
  192. package/lib/module/hooks/roving-focus.js +181 -0
  193. package/lib/module/hooks/roving-focus.js.map +1 -0
  194. package/lib/module/hover-card/index.web.js +5 -0
  195. package/lib/module/hover-card/index.web.js.map +1 -1
  196. package/lib/module/icons/remix/RiBookReadLine.js +9 -0
  197. package/lib/module/icons/remix/RiBookReadLine.js.map +1 -0
  198. package/lib/module/icons/remix/RiBugLine.js +9 -0
  199. package/lib/module/icons/remix/RiBugLine.js.map +1 -0
  200. package/lib/module/icons/remix/RiChat1Line.js +9 -0
  201. package/lib/module/icons/remix/RiChat1Line.js.map +1 -0
  202. package/lib/module/icons/remix/RiCloudLine.js +9 -0
  203. package/lib/module/icons/remix/RiCloudLine.js.map +1 -0
  204. package/lib/module/icons/remix/RiCodeLine.js +9 -0
  205. package/lib/module/icons/remix/RiCodeLine.js.map +1 -0
  206. package/lib/module/icons/remix/RiCpuLine.js +9 -0
  207. package/lib/module/icons/remix/RiCpuLine.js.map +1 -0
  208. package/lib/module/icons/remix/RiFloodLine.js +9 -0
  209. package/lib/module/icons/remix/RiFloodLine.js.map +1 -0
  210. package/lib/module/icons/remix/RiLockUnlockLine.js +9 -0
  211. package/lib/module/icons/remix/RiLockUnlockLine.js.map +1 -0
  212. package/lib/module/icons/remix/RiMoneyDollarCircleLine.js +9 -0
  213. package/lib/module/icons/remix/RiMoneyDollarCircleLine.js.map +1 -0
  214. package/lib/module/icons/remix/RiPlayCircleLine.js +9 -0
  215. package/lib/module/icons/remix/RiPlayCircleLine.js.map +1 -0
  216. package/lib/module/icons/remix/RiRocket2Line.js +9 -0
  217. package/lib/module/icons/remix/RiRocket2Line.js.map +1 -0
  218. package/lib/module/icons/remix/RiServerLine.js +9 -0
  219. package/lib/module/icons/remix/RiServerLine.js.map +1 -0
  220. package/lib/module/icons/remix/RiShareBoxLine.js +9 -0
  221. package/lib/module/icons/remix/RiShareBoxLine.js.map +1 -0
  222. package/lib/module/icons/remix/RiTv2Line.js +9 -0
  223. package/lib/module/icons/remix/RiTv2Line.js.map +1 -0
  224. package/lib/module/icons/remix/index.js +14 -0
  225. package/lib/module/icons/remix/index.js.map +1 -1
  226. package/lib/module/list/index.web.js +5 -0
  227. package/lib/module/list/index.web.js.map +1 -1
  228. package/lib/module/loading/Loading.js +17 -155
  229. package/lib/module/loading/Loading.js.map +1 -1
  230. package/lib/module/loading/Loading.web.js +19 -155
  231. package/lib/module/loading/Loading.web.js.map +1 -1
  232. package/lib/module/loading/LoadingBase.js +194 -0
  233. package/lib/module/loading/LoadingBase.js.map +1 -0
  234. package/lib/module/loading/index.web.js +5 -13
  235. package/lib/module/loading/index.web.js.map +1 -1
  236. package/lib/module/media-flight/index.web.js +5 -9
  237. package/lib/module/media-flight/index.web.js.map +1 -1
  238. package/lib/module/menubar/Menubar.js +15 -122
  239. package/lib/module/menubar/Menubar.js.map +1 -1
  240. package/lib/module/menubar/Menubar.web.js +18 -114
  241. package/lib/module/menubar/Menubar.web.js.map +1 -1
  242. package/lib/module/menubar/MenubarBase.js +146 -0
  243. package/lib/module/menubar/MenubarBase.js.map +1 -0
  244. package/lib/module/menubar/index.web.js +5 -0
  245. package/lib/module/menubar/index.web.js.map +1 -1
  246. package/lib/module/motion/index.web.js +5 -5
  247. package/lib/module/motion/index.web.js.map +1 -1
  248. package/lib/module/popover/index.web.js +5 -0
  249. package/lib/module/popover/index.web.js.map +1 -1
  250. package/lib/module/popover/parts.js +70 -12
  251. package/lib/module/popover/parts.js.map +1 -1
  252. package/lib/module/popover/surface.js +39 -13
  253. package/lib/module/popover/surface.js.map +1 -1
  254. package/lib/module/portal/index.web.js +6 -1
  255. package/lib/module/portal/index.web.js.map +1 -1
  256. package/lib/module/progressive-blur/index.web.js +5 -0
  257. package/lib/module/progressive-blur/index.web.js.map +1 -1
  258. package/lib/module/scroll/index.web.js +5 -0
  259. package/lib/module/scroll/index.web.js.map +1 -1
  260. package/lib/module/segmented-control/SegmentedControl.js +36 -1
  261. package/lib/module/segmented-control/SegmentedControl.js.map +1 -1
  262. package/lib/module/select/Select.js +5 -77
  263. package/lib/module/select/Select.js.map +1 -1
  264. package/lib/module/select/Select.web.js +147 -82
  265. package/lib/module/select/Select.web.js.map +1 -1
  266. package/lib/module/select/index.js +2 -2
  267. package/lib/module/select/index.js.map +1 -1
  268. package/lib/module/select/index.web.js +7 -2
  269. package/lib/module/select/index.web.js.map +1 -1
  270. package/lib/module/select/shared.js +106 -6
  271. package/lib/module/select/shared.js.map +1 -1
  272. package/lib/module/sidebar/SidebarTeamMenu.js +2 -2
  273. package/lib/module/sidebar/SidebarTeamMenu.js.map +1 -1
  274. package/lib/module/sidebar/SidebarUserMenu.js +2 -2
  275. package/lib/module/sidebar/SidebarUserMenu.js.map +1 -1
  276. package/lib/module/sidebar/parts.js +8 -8
  277. package/lib/module/sidebar/parts.js.map +1 -1
  278. package/lib/module/surfaces/SurfaceHost.js +6 -0
  279. package/lib/module/surfaces/SurfaceHost.js.map +1 -1
  280. package/lib/module/surfaces/index.web.js +14 -4
  281. package/lib/module/surfaces/index.web.js.map +1 -1
  282. package/lib/module/tab-bar/index.web.js +13 -10
  283. package/lib/module/tab-bar/index.web.js.map +1 -1
  284. package/lib/module/tabs/Tabs.js +49 -2
  285. package/lib/module/tabs/Tabs.js.map +1 -1
  286. package/lib/module/theme/color-scope/index.web.js +5 -0
  287. package/lib/module/theme/color-scope/index.web.js.map +1 -1
  288. package/lib/module/theme/persistence.js +12 -1
  289. package/lib/module/theme/persistence.js.map +1 -1
  290. package/lib/module/theme/seed-scope/index.web.js +5 -0
  291. package/lib/module/theme/seed-scope/index.web.js.map +1 -1
  292. package/lib/module/tooltip/index.web.js +5 -0
  293. package/lib/module/tooltip/index.web.js.map +1 -1
  294. package/lib/typescript/commonjs/agent-chat/index.web.d.ts.map +1 -1
  295. package/lib/typescript/commonjs/ai-chat/index.web.d.ts.map +1 -1
  296. package/lib/typescript/commonjs/alert-dialog/index.web.d.ts +5 -1
  297. package/lib/typescript/commonjs/alert-dialog/index.web.d.ts.map +1 -1
  298. package/lib/typescript/commonjs/avatar-group/index.web.d.ts.map +1 -1
  299. package/lib/typescript/commonjs/bottom-sheet/index.web.d.ts.map +1 -1
  300. package/lib/typescript/commonjs/code/index.d.ts +2 -0
  301. package/lib/typescript/commonjs/code/index.d.ts.map +1 -1
  302. package/lib/typescript/commonjs/command/index.web.d.ts.map +1 -1
  303. package/lib/typescript/commonjs/composer-loader/ComposerLoader.web.d.ts +8 -0
  304. package/lib/typescript/commonjs/composer-loader/ComposerLoader.web.d.ts.map +1 -1
  305. package/lib/typescript/commonjs/composer-loader/index.web.d.ts.map +1 -1
  306. package/lib/typescript/commonjs/composer-panel/index.web.d.ts.map +1 -1
  307. package/lib/typescript/commonjs/connection-dots/index.web.d.ts.map +1 -1
  308. package/lib/typescript/commonjs/connection-status/index.web.d.ts.map +1 -1
  309. package/lib/typescript/commonjs/content-panel/index.web.d.ts.map +1 -1
  310. package/lib/typescript/commonjs/context-menu/ContextMenu.web.d.ts.map +1 -1
  311. package/lib/typescript/commonjs/context-menu/context.d.ts +3 -0
  312. package/lib/typescript/commonjs/context-menu/context.d.ts.map +1 -1
  313. package/lib/typescript/commonjs/context-menu/index.web.d.ts.map +1 -1
  314. package/lib/typescript/commonjs/dialog/Dialog.web.d.ts.map +1 -1
  315. package/lib/typescript/commonjs/dialog/index.web.d.ts +2 -1
  316. package/lib/typescript/commonjs/dialog/index.web.d.ts.map +1 -1
  317. package/lib/typescript/commonjs/dropdown-menu/DropdownMenu.web.d.ts.map +1 -1
  318. package/lib/typescript/commonjs/dropdown-menu/index.web.d.ts.map +1 -1
  319. package/lib/typescript/commonjs/floating/FloatingPanel.d.ts +1 -1
  320. package/lib/typescript/commonjs/floating/FloatingPanel.d.ts.map +1 -1
  321. package/lib/typescript/commonjs/floating/escape-stack.d.ts +55 -0
  322. package/lib/typescript/commonjs/floating/escape-stack.d.ts.map +1 -0
  323. package/lib/typescript/commonjs/floating/menu-keyboard.d.ts +57 -0
  324. package/lib/typescript/commonjs/floating/menu-keyboard.d.ts.map +1 -0
  325. package/lib/typescript/commonjs/floating/menu-sub-flyout.d.ts.map +1 -1
  326. package/lib/typescript/commonjs/floating/types.d.ts +11 -0
  327. package/lib/typescript/commonjs/floating/types.d.ts.map +1 -1
  328. package/lib/typescript/commonjs/fonts/index.web.d.ts.map +1 -1
  329. package/lib/typescript/commonjs/frosted-icon-button/FrostedIconButton.web.d.ts.map +1 -1
  330. package/lib/typescript/commonjs/frosted-icon-button/index.web.d.ts.map +1 -1
  331. package/lib/typescript/commonjs/hooks/roving-focus.d.ts +66 -0
  332. package/lib/typescript/commonjs/hooks/roving-focus.d.ts.map +1 -0
  333. package/lib/typescript/commonjs/hover-card/index.web.d.ts.map +1 -1
  334. package/lib/typescript/commonjs/icons/remix/RiBookReadLine.d.ts +8 -0
  335. package/lib/typescript/commonjs/icons/remix/RiBookReadLine.d.ts.map +1 -0
  336. package/lib/typescript/commonjs/icons/remix/RiBugLine.d.ts +8 -0
  337. package/lib/typescript/commonjs/icons/remix/RiBugLine.d.ts.map +1 -0
  338. package/lib/typescript/commonjs/icons/remix/RiChat1Line.d.ts +8 -0
  339. package/lib/typescript/commonjs/icons/remix/RiChat1Line.d.ts.map +1 -0
  340. package/lib/typescript/commonjs/icons/remix/RiCloudLine.d.ts +8 -0
  341. package/lib/typescript/commonjs/icons/remix/RiCloudLine.d.ts.map +1 -0
  342. package/lib/typescript/commonjs/icons/remix/RiCodeLine.d.ts +8 -0
  343. package/lib/typescript/commonjs/icons/remix/RiCodeLine.d.ts.map +1 -0
  344. package/lib/typescript/commonjs/icons/remix/RiCpuLine.d.ts +8 -0
  345. package/lib/typescript/commonjs/icons/remix/RiCpuLine.d.ts.map +1 -0
  346. package/lib/typescript/commonjs/icons/remix/RiFloodLine.d.ts +8 -0
  347. package/lib/typescript/commonjs/icons/remix/RiFloodLine.d.ts.map +1 -0
  348. package/lib/typescript/commonjs/icons/remix/RiLockUnlockLine.d.ts +8 -0
  349. package/lib/typescript/commonjs/icons/remix/RiLockUnlockLine.d.ts.map +1 -0
  350. package/lib/typescript/commonjs/icons/remix/RiMoneyDollarCircleLine.d.ts +8 -0
  351. package/lib/typescript/commonjs/icons/remix/RiMoneyDollarCircleLine.d.ts.map +1 -0
  352. package/lib/typescript/commonjs/icons/remix/RiPlayCircleLine.d.ts +8 -0
  353. package/lib/typescript/commonjs/icons/remix/RiPlayCircleLine.d.ts.map +1 -0
  354. package/lib/typescript/commonjs/icons/remix/RiRocket2Line.d.ts +8 -0
  355. package/lib/typescript/commonjs/icons/remix/RiRocket2Line.d.ts.map +1 -0
  356. package/lib/typescript/commonjs/icons/remix/RiServerLine.d.ts +8 -0
  357. package/lib/typescript/commonjs/icons/remix/RiServerLine.d.ts.map +1 -0
  358. package/lib/typescript/commonjs/icons/remix/RiShareBoxLine.d.ts +8 -0
  359. package/lib/typescript/commonjs/icons/remix/RiShareBoxLine.d.ts.map +1 -0
  360. package/lib/typescript/commonjs/icons/remix/RiTv2Line.d.ts +8 -0
  361. package/lib/typescript/commonjs/icons/remix/RiTv2Line.d.ts.map +1 -0
  362. package/lib/typescript/commonjs/icons/remix/index.d.ts +14 -0
  363. package/lib/typescript/commonjs/icons/remix/index.d.ts.map +1 -1
  364. package/lib/typescript/commonjs/list/index.web.d.ts.map +1 -1
  365. package/lib/typescript/commonjs/loading/Loading.d.ts +8 -2
  366. package/lib/typescript/commonjs/loading/Loading.d.ts.map +1 -1
  367. package/lib/typescript/commonjs/loading/Loading.web.d.ts +10 -2
  368. package/lib/typescript/commonjs/loading/Loading.web.d.ts.map +1 -1
  369. package/lib/typescript/commonjs/loading/LoadingBase.d.ts +64 -0
  370. package/lib/typescript/commonjs/loading/LoadingBase.d.ts.map +1 -0
  371. package/lib/typescript/commonjs/loading/index.web.d.ts.map +1 -1
  372. package/lib/typescript/commonjs/media-flight/index.web.d.ts +0 -9
  373. package/lib/typescript/commonjs/media-flight/index.web.d.ts.map +1 -1
  374. package/lib/typescript/commonjs/menubar/Menubar.d.ts +14 -9
  375. package/lib/typescript/commonjs/menubar/Menubar.d.ts.map +1 -1
  376. package/lib/typescript/commonjs/menubar/Menubar.web.d.ts +8 -6
  377. package/lib/typescript/commonjs/menubar/Menubar.web.d.ts.map +1 -1
  378. package/lib/typescript/commonjs/menubar/MenubarBase.d.ts +5 -0
  379. package/lib/typescript/commonjs/menubar/MenubarBase.d.ts.map +1 -0
  380. package/lib/typescript/commonjs/menubar/index.web.d.ts.map +1 -1
  381. package/lib/typescript/commonjs/motion/index.web.d.ts +0 -5
  382. package/lib/typescript/commonjs/motion/index.web.d.ts.map +1 -1
  383. package/lib/typescript/commonjs/popover/index.web.d.ts.map +1 -1
  384. package/lib/typescript/commonjs/popover/parts.d.ts.map +1 -1
  385. package/lib/typescript/commonjs/popover/surface.d.ts +15 -5
  386. package/lib/typescript/commonjs/popover/surface.d.ts.map +1 -1
  387. package/lib/typescript/commonjs/portal/index.web.d.ts +1 -1
  388. package/lib/typescript/commonjs/portal/index.web.d.ts.map +1 -1
  389. package/lib/typescript/commonjs/progressive-blur/index.web.d.ts.map +1 -1
  390. package/lib/typescript/commonjs/scroll/index.web.d.ts.map +1 -1
  391. package/lib/typescript/commonjs/segmented-control/SegmentedControl.d.ts.map +1 -1
  392. package/lib/typescript/commonjs/select/Select.d.ts +2 -4
  393. package/lib/typescript/commonjs/select/Select.d.ts.map +1 -1
  394. package/lib/typescript/commonjs/select/Select.web.d.ts +2 -4
  395. package/lib/typescript/commonjs/select/Select.web.d.ts.map +1 -1
  396. package/lib/typescript/commonjs/select/index.d.ts +2 -2
  397. package/lib/typescript/commonjs/select/index.d.ts.map +1 -1
  398. package/lib/typescript/commonjs/select/index.web.d.ts +2 -2
  399. package/lib/typescript/commonjs/select/index.web.d.ts.map +1 -1
  400. package/lib/typescript/commonjs/select/shared.d.ts +52 -5
  401. package/lib/typescript/commonjs/select/shared.d.ts.map +1 -1
  402. package/lib/typescript/commonjs/select/types.d.ts +6 -0
  403. package/lib/typescript/commonjs/select/types.d.ts.map +1 -1
  404. package/lib/typescript/commonjs/sidebar/parts.d.ts +8 -2
  405. package/lib/typescript/commonjs/sidebar/parts.d.ts.map +1 -1
  406. package/lib/typescript/commonjs/surfaces/SurfaceHost.d.ts.map +1 -1
  407. package/lib/typescript/commonjs/surfaces/index.web.d.ts +9 -4
  408. package/lib/typescript/commonjs/surfaces/index.web.d.ts.map +1 -1
  409. package/lib/typescript/commonjs/tab-bar/index.web.d.ts.map +1 -1
  410. package/lib/typescript/commonjs/tabs/Tabs.d.ts.map +1 -1
  411. package/lib/typescript/commonjs/tabs/types.d.ts +6 -0
  412. package/lib/typescript/commonjs/tabs/types.d.ts.map +1 -1
  413. package/lib/typescript/commonjs/theme/color-scope/index.web.d.ts.map +1 -1
  414. package/lib/typescript/commonjs/theme/persistence.d.ts.map +1 -1
  415. package/lib/typescript/commonjs/theme/seed-scope/index.web.d.ts.map +1 -1
  416. package/lib/typescript/commonjs/tooltip/index.web.d.ts.map +1 -1
  417. package/lib/typescript/module/agent-chat/index.web.d.ts.map +1 -1
  418. package/lib/typescript/module/ai-chat/index.web.d.ts.map +1 -1
  419. package/lib/typescript/module/alert-dialog/index.web.d.ts +5 -1
  420. package/lib/typescript/module/alert-dialog/index.web.d.ts.map +1 -1
  421. package/lib/typescript/module/avatar-group/index.web.d.ts.map +1 -1
  422. package/lib/typescript/module/bottom-sheet/index.web.d.ts.map +1 -1
  423. package/lib/typescript/module/code/index.d.ts +2 -0
  424. package/lib/typescript/module/code/index.d.ts.map +1 -1
  425. package/lib/typescript/module/command/index.web.d.ts.map +1 -1
  426. package/lib/typescript/module/composer-loader/ComposerLoader.web.d.ts +8 -0
  427. package/lib/typescript/module/composer-loader/ComposerLoader.web.d.ts.map +1 -1
  428. package/lib/typescript/module/composer-loader/index.web.d.ts.map +1 -1
  429. package/lib/typescript/module/composer-panel/index.web.d.ts.map +1 -1
  430. package/lib/typescript/module/connection-dots/index.web.d.ts.map +1 -1
  431. package/lib/typescript/module/connection-status/index.web.d.ts.map +1 -1
  432. package/lib/typescript/module/content-panel/index.web.d.ts.map +1 -1
  433. package/lib/typescript/module/context-menu/ContextMenu.web.d.ts.map +1 -1
  434. package/lib/typescript/module/context-menu/context.d.ts +3 -0
  435. package/lib/typescript/module/context-menu/context.d.ts.map +1 -1
  436. package/lib/typescript/module/context-menu/index.web.d.ts.map +1 -1
  437. package/lib/typescript/module/dialog/Dialog.web.d.ts.map +1 -1
  438. package/lib/typescript/module/dialog/index.web.d.ts +2 -1
  439. package/lib/typescript/module/dialog/index.web.d.ts.map +1 -1
  440. package/lib/typescript/module/dropdown-menu/DropdownMenu.web.d.ts.map +1 -1
  441. package/lib/typescript/module/dropdown-menu/index.web.d.ts.map +1 -1
  442. package/lib/typescript/module/floating/FloatingPanel.d.ts +1 -1
  443. package/lib/typescript/module/floating/FloatingPanel.d.ts.map +1 -1
  444. package/lib/typescript/module/floating/escape-stack.d.ts +55 -0
  445. package/lib/typescript/module/floating/escape-stack.d.ts.map +1 -0
  446. package/lib/typescript/module/floating/menu-keyboard.d.ts +57 -0
  447. package/lib/typescript/module/floating/menu-keyboard.d.ts.map +1 -0
  448. package/lib/typescript/module/floating/menu-sub-flyout.d.ts.map +1 -1
  449. package/lib/typescript/module/floating/types.d.ts +11 -0
  450. package/lib/typescript/module/floating/types.d.ts.map +1 -1
  451. package/lib/typescript/module/fonts/index.web.d.ts.map +1 -1
  452. package/lib/typescript/module/frosted-icon-button/FrostedIconButton.web.d.ts.map +1 -1
  453. package/lib/typescript/module/frosted-icon-button/index.web.d.ts.map +1 -1
  454. package/lib/typescript/module/hooks/roving-focus.d.ts +66 -0
  455. package/lib/typescript/module/hooks/roving-focus.d.ts.map +1 -0
  456. package/lib/typescript/module/hover-card/index.web.d.ts.map +1 -1
  457. package/lib/typescript/module/icons/remix/RiBookReadLine.d.ts +8 -0
  458. package/lib/typescript/module/icons/remix/RiBookReadLine.d.ts.map +1 -0
  459. package/lib/typescript/module/icons/remix/RiBugLine.d.ts +8 -0
  460. package/lib/typescript/module/icons/remix/RiBugLine.d.ts.map +1 -0
  461. package/lib/typescript/module/icons/remix/RiChat1Line.d.ts +8 -0
  462. package/lib/typescript/module/icons/remix/RiChat1Line.d.ts.map +1 -0
  463. package/lib/typescript/module/icons/remix/RiCloudLine.d.ts +8 -0
  464. package/lib/typescript/module/icons/remix/RiCloudLine.d.ts.map +1 -0
  465. package/lib/typescript/module/icons/remix/RiCodeLine.d.ts +8 -0
  466. package/lib/typescript/module/icons/remix/RiCodeLine.d.ts.map +1 -0
  467. package/lib/typescript/module/icons/remix/RiCpuLine.d.ts +8 -0
  468. package/lib/typescript/module/icons/remix/RiCpuLine.d.ts.map +1 -0
  469. package/lib/typescript/module/icons/remix/RiFloodLine.d.ts +8 -0
  470. package/lib/typescript/module/icons/remix/RiFloodLine.d.ts.map +1 -0
  471. package/lib/typescript/module/icons/remix/RiLockUnlockLine.d.ts +8 -0
  472. package/lib/typescript/module/icons/remix/RiLockUnlockLine.d.ts.map +1 -0
  473. package/lib/typescript/module/icons/remix/RiMoneyDollarCircleLine.d.ts +8 -0
  474. package/lib/typescript/module/icons/remix/RiMoneyDollarCircleLine.d.ts.map +1 -0
  475. package/lib/typescript/module/icons/remix/RiPlayCircleLine.d.ts +8 -0
  476. package/lib/typescript/module/icons/remix/RiPlayCircleLine.d.ts.map +1 -0
  477. package/lib/typescript/module/icons/remix/RiRocket2Line.d.ts +8 -0
  478. package/lib/typescript/module/icons/remix/RiRocket2Line.d.ts.map +1 -0
  479. package/lib/typescript/module/icons/remix/RiServerLine.d.ts +8 -0
  480. package/lib/typescript/module/icons/remix/RiServerLine.d.ts.map +1 -0
  481. package/lib/typescript/module/icons/remix/RiShareBoxLine.d.ts +8 -0
  482. package/lib/typescript/module/icons/remix/RiShareBoxLine.d.ts.map +1 -0
  483. package/lib/typescript/module/icons/remix/RiTv2Line.d.ts +8 -0
  484. package/lib/typescript/module/icons/remix/RiTv2Line.d.ts.map +1 -0
  485. package/lib/typescript/module/icons/remix/index.d.ts +14 -0
  486. package/lib/typescript/module/icons/remix/index.d.ts.map +1 -1
  487. package/lib/typescript/module/list/index.web.d.ts.map +1 -1
  488. package/lib/typescript/module/loading/Loading.d.ts +8 -2
  489. package/lib/typescript/module/loading/Loading.d.ts.map +1 -1
  490. package/lib/typescript/module/loading/Loading.web.d.ts +10 -2
  491. package/lib/typescript/module/loading/Loading.web.d.ts.map +1 -1
  492. package/lib/typescript/module/loading/LoadingBase.d.ts +64 -0
  493. package/lib/typescript/module/loading/LoadingBase.d.ts.map +1 -0
  494. package/lib/typescript/module/loading/index.web.d.ts.map +1 -1
  495. package/lib/typescript/module/media-flight/index.web.d.ts +0 -9
  496. package/lib/typescript/module/media-flight/index.web.d.ts.map +1 -1
  497. package/lib/typescript/module/menubar/Menubar.d.ts +14 -9
  498. package/lib/typescript/module/menubar/Menubar.d.ts.map +1 -1
  499. package/lib/typescript/module/menubar/Menubar.web.d.ts +8 -6
  500. package/lib/typescript/module/menubar/Menubar.web.d.ts.map +1 -1
  501. package/lib/typescript/module/menubar/MenubarBase.d.ts +5 -0
  502. package/lib/typescript/module/menubar/MenubarBase.d.ts.map +1 -0
  503. package/lib/typescript/module/menubar/index.web.d.ts.map +1 -1
  504. package/lib/typescript/module/motion/index.web.d.ts +0 -5
  505. package/lib/typescript/module/motion/index.web.d.ts.map +1 -1
  506. package/lib/typescript/module/popover/index.web.d.ts.map +1 -1
  507. package/lib/typescript/module/popover/parts.d.ts.map +1 -1
  508. package/lib/typescript/module/popover/surface.d.ts +15 -5
  509. package/lib/typescript/module/popover/surface.d.ts.map +1 -1
  510. package/lib/typescript/module/portal/index.web.d.ts +1 -1
  511. package/lib/typescript/module/portal/index.web.d.ts.map +1 -1
  512. package/lib/typescript/module/progressive-blur/index.web.d.ts.map +1 -1
  513. package/lib/typescript/module/scroll/index.web.d.ts.map +1 -1
  514. package/lib/typescript/module/segmented-control/SegmentedControl.d.ts.map +1 -1
  515. package/lib/typescript/module/select/Select.d.ts +2 -4
  516. package/lib/typescript/module/select/Select.d.ts.map +1 -1
  517. package/lib/typescript/module/select/Select.web.d.ts +2 -4
  518. package/lib/typescript/module/select/Select.web.d.ts.map +1 -1
  519. package/lib/typescript/module/select/index.d.ts +2 -2
  520. package/lib/typescript/module/select/index.d.ts.map +1 -1
  521. package/lib/typescript/module/select/index.web.d.ts +2 -2
  522. package/lib/typescript/module/select/index.web.d.ts.map +1 -1
  523. package/lib/typescript/module/select/shared.d.ts +52 -5
  524. package/lib/typescript/module/select/shared.d.ts.map +1 -1
  525. package/lib/typescript/module/select/types.d.ts +6 -0
  526. package/lib/typescript/module/select/types.d.ts.map +1 -1
  527. package/lib/typescript/module/sidebar/parts.d.ts +8 -2
  528. package/lib/typescript/module/sidebar/parts.d.ts.map +1 -1
  529. package/lib/typescript/module/surfaces/SurfaceHost.d.ts.map +1 -1
  530. package/lib/typescript/module/surfaces/index.web.d.ts +9 -4
  531. package/lib/typescript/module/surfaces/index.web.d.ts.map +1 -1
  532. package/lib/typescript/module/tab-bar/index.web.d.ts.map +1 -1
  533. package/lib/typescript/module/tabs/Tabs.d.ts.map +1 -1
  534. package/lib/typescript/module/tabs/types.d.ts +6 -0
  535. package/lib/typescript/module/tabs/types.d.ts.map +1 -1
  536. package/lib/typescript/module/theme/color-scope/index.web.d.ts.map +1 -1
  537. package/lib/typescript/module/theme/persistence.d.ts.map +1 -1
  538. package/lib/typescript/module/theme/seed-scope/index.web.d.ts.map +1 -1
  539. package/lib/typescript/module/tooltip/index.web.d.ts.map +1 -1
  540. package/package.json +1 -1
  541. package/src/agent-chat/index.web.ts +5 -3
  542. package/src/ai-chat/index.web.ts +5 -2
  543. package/src/alert-dialog/index.web.ts +10 -1
  544. package/src/avatar-group/index.web.ts +5 -0
  545. package/src/bottom-sheet/index.web.ts +5 -0
  546. package/src/code/index.ts +2 -0
  547. package/src/command/index.web.ts +5 -0
  548. package/src/composer-loader/ComposerLoader.web.tsx +8 -0
  549. package/src/composer-loader/index.web.ts +5 -2
  550. package/src/composer-panel/index.web.ts +5 -3
  551. package/src/connection-dots/index.web.ts +5 -0
  552. package/src/connection-status/index.web.ts +5 -0
  553. package/src/content-panel/index.web.ts +5 -0
  554. package/src/context-menu/ContextMenu.web.tsx +26 -3
  555. package/src/context-menu/context.ts +3 -0
  556. package/src/context-menu/index.web.ts +5 -0
  557. package/src/dialog/Dialog.web.tsx +13 -0
  558. package/src/dialog/index.web.ts +7 -11
  559. package/src/dropdown-menu/DropdownMenu.web.tsx +25 -2
  560. package/src/dropdown-menu/index.web.ts +5 -0
  561. package/src/floating/FloatingPanel.tsx +37 -38
  562. package/src/floating/escape-stack.ts +92 -0
  563. package/src/floating/menu-keyboard.ts +242 -0
  564. package/src/floating/menu-sub-flyout.tsx +22 -17
  565. package/src/floating/types.ts +11 -0
  566. package/src/fonts/index.web.ts +5 -20
  567. package/src/frosted-icon-button/FrostedIconButton.web.tsx +9 -0
  568. package/src/frosted-icon-button/index.web.ts +5 -7
  569. package/src/hooks/roving-focus.ts +204 -0
  570. package/src/hover-card/index.web.ts +5 -0
  571. package/src/icons/remix/RiBookReadLine.tsx +6 -0
  572. package/src/icons/remix/RiBugLine.tsx +6 -0
  573. package/src/icons/remix/RiChat1Line.tsx +6 -0
  574. package/src/icons/remix/RiCloudLine.tsx +6 -0
  575. package/src/icons/remix/RiCodeLine.tsx +6 -0
  576. package/src/icons/remix/RiCpuLine.tsx +6 -0
  577. package/src/icons/remix/RiFloodLine.tsx +6 -0
  578. package/src/icons/remix/RiLockUnlockLine.tsx +6 -0
  579. package/src/icons/remix/RiMoneyDollarCircleLine.tsx +6 -0
  580. package/src/icons/remix/RiPlayCircleLine.tsx +6 -0
  581. package/src/icons/remix/RiRocket2Line.tsx +6 -0
  582. package/src/icons/remix/RiServerLine.tsx +6 -0
  583. package/src/icons/remix/RiShareBoxLine.tsx +6 -0
  584. package/src/icons/remix/RiTv2Line.tsx +6 -0
  585. package/src/icons/remix/index.ts +14 -0
  586. package/src/list/index.web.ts +5 -0
  587. package/src/loading/Loading.tsx +15 -135
  588. package/src/loading/Loading.web.tsx +16 -134
  589. package/src/loading/LoadingBase.tsx +170 -0
  590. package/src/loading/index.web.ts +5 -13
  591. package/src/media-flight/index.web.ts +5 -9
  592. package/src/menubar/Menubar.tsx +16 -147
  593. package/src/menubar/Menubar.web.tsx +15 -138
  594. package/src/menubar/MenubarBase.tsx +170 -0
  595. package/src/menubar/index.web.ts +5 -0
  596. package/src/motion/index.web.ts +5 -5
  597. package/src/popover/index.web.ts +5 -0
  598. package/src/popover/parts.tsx +76 -12
  599. package/src/popover/surface.ts +68 -15
  600. package/src/portal/index.web.ts +6 -1
  601. package/src/progressive-blur/index.web.ts +5 -0
  602. package/src/scroll/index.web.ts +5 -0
  603. package/src/segmented-control/SegmentedControl.tsx +45 -1
  604. package/src/select/Select.tsx +4 -67
  605. package/src/select/Select.web.tsx +133 -69
  606. package/src/select/index.ts +3 -3
  607. package/src/select/index.web.ts +8 -3
  608. package/src/select/shared.tsx +107 -5
  609. package/src/select/types.ts +6 -0
  610. package/src/sidebar/SidebarTeamMenu.tsx +2 -2
  611. package/src/sidebar/SidebarUserMenu.tsx +2 -2
  612. package/src/sidebar/parts.tsx +8 -9
  613. package/src/surfaces/SurfaceHost.tsx +6 -0
  614. package/src/surfaces/index.web.ts +14 -4
  615. package/src/tab-bar/index.web.ts +13 -10
  616. package/src/tabs/Tabs.tsx +65 -1
  617. package/src/tabs/types.ts +6 -0
  618. package/src/theme/color-scope/index.web.ts +5 -0
  619. package/src/theme/persistence.ts +11 -1
  620. package/src/theme/seed-scope/index.web.ts +5 -0
  621. package/src/tooltip/index.web.ts +5 -0
@@ -1,3 +1,8 @@
1
+ // AUTO-GENERATED by scripts/generate-platform-exports.mjs — DO NOT EDIT.
2
+ // Source of truth: src/dropdown-menu/index.ts.
3
+ // Re-run `bun run generate:exports` (or any `bun run build`) after
4
+ // changing that barrel or the set of web-forked subpaths.
5
+
1
6
  export {
2
7
  DropdownMenu,
3
8
  DropdownMenuTrigger,
@@ -89,6 +89,7 @@ import {
89
89
  VIEWPORT_GUTTER,
90
90
  } from './constants';
91
91
  import { useMenuPalette } from './menu-palette';
92
+ import { pushFloatingEscape } from './escape-stack';
92
93
  import { cx } from './shared';
93
94
  import type { FloatingPanelProps, FloatingSide } from './types';
94
95
  import { useFrameThrottle } from './use-frame-throttle';
@@ -105,36 +106,31 @@ const AnimatedPanel = Animated.createAnimatedComponent(StyledView);
105
106
  const MENU_EASING = Easing.bezier(...MENU_MOTION_EASING);
106
107
 
107
108
  /**
108
- * The per-surface chrome and motion. All three share the one popover motion;
109
- * `menu` and `listbox` use the menu recipe (`menu-styles.ts`) with colours from
110
- * `menu-palette.ts`, while `popover` leaves the whole panel to its caller's
111
- * resolved `style` (`popover/surface.ts`).
109
+ * The ONE motion every anchored surface runs: 150ms `ease-out`, fade +
110
+ * `scale-95` + 2px blur, no slide, scaling from the corner nearest the
111
+ * trigger, and the same shape reversed on the way out. It was written out
112
+ * three times, once per surface, with only the chrome differing — three
113
+ * spellings of one decision, any of which could be edited alone.
114
+ */
115
+ const MENU_MOTION = {
116
+ duration: MENU_MOTION_DURATION,
117
+ easing: MENU_EASING,
118
+ scaleFrom: MENU_MOTION_SCALE_FROM,
119
+ slide: 0,
120
+ blur: MENU_MOTION_BLUR,
121
+ } as const;
122
+
123
+ /**
124
+ * The per-surface chrome. `menu` and `listbox` use the menu recipe
125
+ * (`constants.ts`'s `MENU_PANEL_CLASS` / `LISTBOX_PANEL_CLASS`) with colours
126
+ * from `menu-palette.ts`; `popover` carries NO chrome of its own here, because
127
+ * `popover/surface.ts` resolves the whole panel inline and hands it over as
128
+ * `style` so a caller's `className` can still override any one piece of it.
112
129
  */
113
130
  const SURFACE = {
114
- popover: {
115
- className: '',
116
- duration: MENU_MOTION_DURATION,
117
- easing: MENU_EASING,
118
- scaleFrom: MENU_MOTION_SCALE_FROM,
119
- slide: 0,
120
- blur: MENU_MOTION_BLUR,
121
- },
122
- menu: {
123
- className: MENU_PANEL_CLASS,
124
- duration: MENU_MOTION_DURATION,
125
- easing: MENU_EASING,
126
- scaleFrom: MENU_MOTION_SCALE_FROM,
127
- slide: 0,
128
- blur: MENU_MOTION_BLUR,
129
- },
130
- listbox: {
131
- className: LISTBOX_PANEL_CLASS,
132
- duration: MENU_MOTION_DURATION,
133
- easing: MENU_EASING,
134
- scaleFrom: MENU_MOTION_SCALE_FROM,
135
- slide: 0,
136
- blur: MENU_MOTION_BLUR,
137
- },
131
+ popover: { ...MENU_MOTION, className: '' },
132
+ menu: { ...MENU_MOTION, className: MENU_PANEL_CLASS },
133
+ listbox: { ...MENU_MOTION, className: LISTBOX_PANEL_CLASS },
138
134
  } as const;
139
135
 
140
136
  /**
@@ -203,6 +199,7 @@ export function FloatingPanel({
203
199
  testID,
204
200
  children,
205
201
  surface = 'popover',
202
+ panelRef,
206
203
  }: FloatingPanelProps) {
207
204
  const chrome = SURFACE[surface];
208
205
  const isMenuSurface = surface !== 'popover';
@@ -224,8 +221,11 @@ export function FloatingPanel({
224
221
  const reducedMotion = useReducedMotion();
225
222
  const progress = useSharedValue(0);
226
223
 
224
+ const panelRefRef = useRef(panelRef);
225
+ panelRefRef.current = panelRef;
227
226
  const attach = useCallback((node: View | null) => {
228
227
  setPanelNode(node);
228
+ panelRefRef.current?.(node);
229
229
  }, []);
230
230
 
231
231
  const store = useCallback((next: DropdownPlacement | null) => {
@@ -438,18 +438,17 @@ export function FloatingPanel({
438
438
  [progress, slideX, slideY, scaleFrom, blurFrom],
439
439
  );
440
440
 
441
+ // Escape dismisses the INNERMOST open surface and nothing under it — a Select
442
+ // inside a Dialog closes its list, not the dialog (`escape-stack.ts`). The
443
+ // entry is taken once per open and calls the CURRENT `onDismiss` through a
444
+ // ref: re-pushing it whenever the callback's identity changed would move a
445
+ // re-rendered parent menu above its own open submenu.
446
+ const onDismissRef = useRef(onDismiss);
447
+ onDismissRef.current = onDismiss;
441
448
  useEffect(() => {
442
449
  if (phase !== 'open' || !dismissible || typeof document === 'undefined') return;
443
- const onKeyDown = (event: KeyboardEvent) => {
444
- if (event.key !== 'Escape') return;
445
- // Stop the key reaching a Dialog underneath: the innermost open surface is
446
- // the one Escape dismisses.
447
- event.stopPropagation();
448
- onDismiss();
449
- };
450
- document.addEventListener('keydown', onKeyDown);
451
- return () => document.removeEventListener('keydown', onKeyDown);
452
- }, [phase, dismissible, onDismiss]);
450
+ return pushFloatingEscape(() => onDismissRef.current());
451
+ }, [phase, dismissible]);
453
452
 
454
453
  // The NON-modal outside press. Deliberately `pointerdown` in the CAPTURE
455
454
  // phase and never `preventDefault`: the surface has to be gone before the
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Escape for the anchored surfaces — WEB. One listener for every open
3
+ * `FloatingPanel`, dismissing only the INNERMOST (most recently opened) one and
4
+ * keeping the key from every enclosing surface.
5
+ *
6
+ * THE DEFECT IT REPLACES. Each panel added its own bubble-phase `keydown`
7
+ * listener on `document` and called `stopPropagation()`. A `Dialog` listens on
8
+ * `document` too, and `stopPropagation` does not stop a SIBLING listener on the
9
+ * same node: listeners on one node run in registration order, and the dialog —
10
+ * open first — registered first. So Escape on a `Select` inside a `Dialog`
11
+ * closed the DIALOG, and the list with it. Two panels open at once (a select
12
+ * inside a popover) had the same shape: the outer one registered first and
13
+ * closed first.
14
+ *
15
+ * THE MECHANISM.
16
+ *
17
+ * - The listener sits on `document.documentElement` in the BUBBLE phase. That
18
+ * is one node BELOW `document`, so it runs before any `document` listener —
19
+ * the Dialog's included — and its `stopPropagation()` keeps the key from
20
+ * ever reaching them. It is also ABOVE React's roots (the app root and every
21
+ * portal container sit inside `<body>`), so a control inside a panel still
22
+ * sees Escape first and can keep it — the composer's model-picker search
23
+ * clears its query on Escape and stops the key, exactly as it did when the
24
+ * panel listened on `document`.
25
+ * - Entries form a stack: the panel opened LAST is dismissed, whatever order
26
+ * the listeners happen to be in.
27
+ * - `hasOpenFloatingSurface()` lets the surface host's window-capture Escape
28
+ * router (`surfaces/SurfaceHost.tsx`) stand aside while a panel is open. It
29
+ * runs before anything here, so without the check it would dismiss the
30
+ * stacked dialog UNDER the open list.
31
+ *
32
+ * `globalThis`-anchored for the same reason as `overlay/stack.ts`: the families
33
+ * that open panels are imported through different subpaths, and a bundler can
34
+ * resolve two physical copies of this module.
35
+ */
36
+
37
+ interface EscapeEntry {
38
+ dismiss: () => void;
39
+ }
40
+
41
+ interface EscapeRegistry {
42
+ stack: EscapeEntry[];
43
+ listener: ((event: KeyboardEvent) => void) | null;
44
+ }
45
+
46
+ declare global {
47
+ // eslint-disable-next-line no-var
48
+ var __oxy_so_bloom_floating_escape__: EscapeRegistry | undefined;
49
+ }
50
+
51
+ function registry(): EscapeRegistry {
52
+ globalThis.__oxy_so_bloom_floating_escape__ ??= { stack: [], listener: null };
53
+ return globalThis.__oxy_so_bloom_floating_escape__;
54
+ }
55
+
56
+ function onKeyDown(event: KeyboardEvent): void {
57
+ if (event.key !== 'Escape') return;
58
+ const stack = registry().stack;
59
+ const top = stack[stack.length - 1];
60
+ if (!top) return;
61
+ event.stopPropagation();
62
+ top.dismiss();
63
+ }
64
+
65
+ /**
66
+ * Put an open surface on top of the Escape stack. Returns the release, which
67
+ * removes exactly this entry wherever it now sits — a parent can close before
68
+ * its submenu's effect cleanup runs.
69
+ */
70
+ export function pushFloatingEscape(dismiss: () => void): () => void {
71
+ const reg = registry();
72
+ const entry: EscapeEntry = { dismiss };
73
+ reg.stack.push(entry);
74
+ if (!reg.listener && typeof document !== 'undefined') {
75
+ reg.listener = onKeyDown;
76
+ document.documentElement.addEventListener('keydown', onKeyDown);
77
+ }
78
+ return () => {
79
+ const current = registry();
80
+ const index = current.stack.indexOf(entry);
81
+ if (index >= 0) current.stack.splice(index, 1);
82
+ if (current.stack.length === 0 && current.listener && typeof document !== 'undefined') {
83
+ document.documentElement.removeEventListener('keydown', current.listener);
84
+ current.listener = null;
85
+ }
86
+ };
87
+ }
88
+
89
+ /** Whether an anchored surface is open and will take the next Escape. */
90
+ export function hasOpenFloatingSurface(): boolean {
91
+ return registry().stack.length > 0;
92
+ }
@@ -0,0 +1,242 @@
1
+ /**
2
+ * The keyboard half of the ARIA menu-button pattern for the anchored menus —
3
+ * `DropdownMenu`, `ContextMenu`, `Menubar` and their flyout sub-menus — on WEB.
4
+ *
5
+ * What shipped: the trigger opened the menu on Enter/Space (it is a real
6
+ * `<button>`) and focus STAYED on it. The rows are portaled to the end of
7
+ * `<body>`, so the arrow keys had nothing to move, Tab walked on through the
8
+ * page BEHIND the open menu, and a keyboard user could open a menu and choose
9
+ * nothing. The markup was right throughout (`role="menu"`, `menuitem`,
10
+ * `aria-checked`), which is why nothing flagged it.
11
+ *
12
+ * The contract now:
13
+ *
14
+ * - Opening from the keyboard moves focus INTO the menu: Enter, Space and
15
+ * ArrowDown land on the first enabled row, ArrowUp on the last. A pointer
16
+ * open leaves focus where the pointer put it; an arrow on the trigger of an
17
+ * already-open menu then moves it in.
18
+ * - In the menu: ArrowDown/ArrowUp move between enabled rows and WRAP;
19
+ * Home/End jump to the ends; Enter and Space activate the row — a checkbox
20
+ * row toggles, a radio row selects, and a row's `keepOpen` still decides
21
+ * whether the menu closes. react-native-web presses a `menuitem`, `checkbox`
22
+ * or `radio` on Enter only (`PressResponder.isValidKeyPress` limits Space to
23
+ * `role="button"`), so Space is supplied here.
24
+ * - Tab closes the menu and returns focus to the trigger — a menu is not in
25
+ * the page's tab sequence. Escape closes the innermost surface
26
+ * (`escape-stack.ts`) and focus returns the same way.
27
+ * - The sub-menu keys stay `menu-sub-flyout.tsx`'s: → on a sub trigger opens
28
+ * the flyout and focuses its first row, ← inside it closes it and refocuses
29
+ * the trigger row.
30
+ *
31
+ * DOM listeners rather than props, like the sub-menu's: a row is
32
+ * `shared.tsx`'s `MenuRowShell`, the trigger may be the caller's own element
33
+ * under `asChild`, and the order of rows is whatever the caller rendered —
34
+ * the DOM already holds all of it. Every entry point is inert without a DOM
35
+ * node, so native (the menu is a bottom sheet there) is untouched.
36
+ */
37
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
38
+
39
+ import { isSpaceKey, rovingItems, rovingMove, rovingTarget } from '../hooks/roving-focus';
40
+ import { MENU_MOTION_DURATION } from './constants';
41
+
42
+ /** Every role a menu ROW can carry — the rows a pointer or a key can land on. */
43
+ export const MENU_ROW_SELECTOR =
44
+ '[role="menuitem"], [role="menuitemcheckbox"], [role="menuitemradio"], [role="checkbox"], [role="radio"]';
45
+
46
+ /** A panel, so a nested panel's rows are never counted as this one's. */
47
+ const MENU_PANEL_SELECTOR = '[role="menu"]';
48
+
49
+ export type MenuFocusEdge = 'first' | 'last';
50
+
51
+ /**
52
+ * Where focus should land the next time the menu's panel is ready — set by a
53
+ * key on the trigger, consumed by the panel. Owned by the family ROOT, which is
54
+ * the one component both the trigger and the content can reach.
55
+ */
56
+ export interface MenuFocusIntent {
57
+ /** The pending edge, or `null` for "leave focus alone" (a pointer open). */
58
+ edge: React.MutableRefObject<MenuFocusEdge | null>;
59
+ /** Bumped to ask an ALREADY-open panel to take focus. */
60
+ tick: number;
61
+ request: (edge: MenuFocusEdge) => void;
62
+ }
63
+
64
+ export function useMenuFocusIntent(): MenuFocusIntent {
65
+ const edge = useRef<MenuFocusEdge | null>(null);
66
+ const [tick, setTick] = useState(0);
67
+ const request = useCallback((next: MenuFocusEdge) => {
68
+ edge.current = next;
69
+ setTick((count) => count + 1);
70
+ }, []);
71
+ return useMemo(() => ({ edge, tick, request }), [tick, request]);
72
+ }
73
+
74
+ /** A react-native-web host ref, read as the DOM element it is on web. */
75
+ export function hostElement(node: unknown): HTMLElement | null {
76
+ if (!node || typeof node !== 'object') return null;
77
+ const scrollable = (node as { getScrollableNode?: () => unknown }).getScrollableNode?.();
78
+ const element = (scrollable ?? node) as Partial<HTMLElement>;
79
+ return typeof element.querySelector === 'function' &&
80
+ typeof element.addEventListener === 'function'
81
+ ? (element as HTMLElement)
82
+ : null;
83
+ }
84
+
85
+ /** The trigger's own focusable control inside its anchor wrapper. */
86
+ export function triggerControl(anchor: unknown): HTMLElement | null {
87
+ const wrapper = hostElement(anchor);
88
+ return (
89
+ wrapper?.querySelector<HTMLElement>('[aria-haspopup]') ??
90
+ wrapper?.querySelector<HTMLElement>('[tabindex]') ??
91
+ null
92
+ );
93
+ }
94
+
95
+ /**
96
+ * Hand focus back to the trigger when a surface closes with focus inside it.
97
+ *
98
+ * `isInside` says whether an element belongs to the surface. Checked AT the
99
+ * close, when the panel is still mounted for its exit animation, so a row that
100
+ * was just activated still counts. Focus that has already gone somewhere real
101
+ * — a dialog the row opened, a field the pointer clicked — is left alone. The
102
+ * one deferred case is focus left on a node the exit is about to UNMOUNT (the
103
+ * outside-press backdrop): once the exit has run and focus has fallen to
104
+ * `<body>`, it goes back to the trigger too.
105
+ */
106
+ export function useReturnFocusOnClose(
107
+ anchorRef: React.RefObject<unknown>,
108
+ open: boolean,
109
+ isInside: (element: Element) => boolean,
110
+ ): void {
111
+ const wasOpen = useRef(open);
112
+ const isInsideRef = useRef(isInside);
113
+ isInsideRef.current = isInside;
114
+ useEffect(() => {
115
+ const closed = wasOpen.current && !open;
116
+ wasOpen.current = open;
117
+ if (!closed || typeof document === 'undefined') return undefined;
118
+ const active = document.activeElement;
119
+ if (!active || active === document.body || isInsideRef.current(active)) {
120
+ triggerControl(anchorRef.current)?.focus({ preventScroll: true });
121
+ return undefined;
122
+ }
123
+ const timer = setTimeout(() => {
124
+ if (document.activeElement === document.body && !active.isConnected) {
125
+ triggerControl(anchorRef.current)?.focus({ preventScroll: true });
126
+ }
127
+ }, MENU_MOTION_DURATION + 50);
128
+ return () => clearTimeout(timer);
129
+ }, [open, anchorRef]);
130
+ }
131
+
132
+ /** Whether an element is one of the menu surfaces — any panel, any depth. */
133
+ export function isInMenuSurface(element: Element): boolean {
134
+ return element.closest(MENU_PANEL_SELECTOR) !== null;
135
+ }
136
+
137
+ /**
138
+ * The menu trigger's keys, on its anchor wrapper: Enter/Space mark a closed
139
+ * menu's open as a keyboard one (the press itself is the button's own);
140
+ * ArrowDown/ArrowUp open it — or, open already, move focus in — landing on the
141
+ * first/last row. Plus the focus return on close.
142
+ */
143
+ export function useMenuTriggerKeys(
144
+ anchorRef: React.RefObject<unknown>,
145
+ {
146
+ open,
147
+ setOpen,
148
+ disabled,
149
+ intent,
150
+ }: {
151
+ open: boolean;
152
+ setOpen: (next: boolean) => void;
153
+ disabled?: boolean;
154
+ intent: MenuFocusIntent | undefined;
155
+ },
156
+ ): void {
157
+ const edge = intent?.edge;
158
+ const request = intent?.request;
159
+ useEffect(() => {
160
+ const wrapper = hostElement(anchorRef.current);
161
+ if (!wrapper || disabled || !edge || !request) return undefined;
162
+ const onKeyDown = (event: KeyboardEvent) => {
163
+ if (event.defaultPrevented) return;
164
+ if (event.key === 'Enter' || isSpaceKey(event.key)) {
165
+ if (!open) edge.current = 'first';
166
+ return;
167
+ }
168
+ if (event.key !== 'ArrowDown' && event.key !== 'ArrowUp') return;
169
+ event.preventDefault();
170
+ if (!open) setOpen(true);
171
+ request(event.key === 'ArrowDown' ? 'first' : 'last');
172
+ };
173
+ wrapper.addEventListener('keydown', onKeyDown);
174
+ return () => wrapper.removeEventListener('keydown', onKeyDown);
175
+ }, [anchorRef, disabled, open, setOpen, edge, request]);
176
+
177
+ // A pointer open must not inherit a stale keyboard intent from a key that
178
+ // did not open anything (a disabled row, a prevented press).
179
+ useEffect(() => {
180
+ if (!open && edge) edge.current = null;
181
+ }, [open, edge]);
182
+
183
+ useReturnFocusOnClose(anchorRef, open, isInMenuSurface);
184
+ }
185
+
186
+ /** The enabled rows that belong to `panel`, in document order. */
187
+ function menuRows(panel: Element): HTMLElement[] {
188
+ // The owner is the nearest `role="menu"` — the panel itself, or (for a sub
189
+ // panel, whose rows sit in an inner scroller) the panel around it.
190
+ const owner = panel.closest(MENU_PANEL_SELECTOR) ?? panel;
191
+ return rovingItems(owner, MENU_ROW_SELECTOR, { owner: MENU_PANEL_SELECTOR });
192
+ }
193
+
194
+ /**
195
+ * The keys inside an open menu panel: arrows (wrapping), Home/End, Space, Tab.
196
+ * `intent`, when given, lands focus on the first/last row as the panel opens
197
+ * from the keyboard (a sub-panel focuses its own first row and passes none).
198
+ */
199
+ export function useMenuPanelKeys(
200
+ panel: HTMLElement | null,
201
+ { open, onTab, intent }: { open: boolean; onTab: () => void; intent?: MenuFocusIntent },
202
+ ): void {
203
+ const onTabRef = useRef(onTab);
204
+ onTabRef.current = onTab;
205
+
206
+ const edge = intent?.edge;
207
+ const tick = intent?.tick;
208
+ useEffect(() => {
209
+ if (!open || !panel || !edge?.current) return;
210
+ const rows = menuRows(panel);
211
+ const target = edge.current === 'last' ? rows[rows.length - 1] : rows[0];
212
+ edge.current = null;
213
+ target?.focus({ preventScroll: true });
214
+ }, [open, panel, edge, tick]);
215
+
216
+ useEffect(() => {
217
+ if (!panel || !open) return undefined;
218
+ const onKeyDown = (event: KeyboardEvent) => {
219
+ if (event.defaultPrevented) return;
220
+ const active =
221
+ typeof document !== 'undefined' ? (document.activeElement as HTMLElement | null) : null;
222
+ const current = active?.closest?.(MENU_ROW_SELECTOR) ?? null;
223
+ if (event.key === 'Tab') {
224
+ event.preventDefault();
225
+ onTabRef.current();
226
+ return;
227
+ }
228
+ if (isSpaceKey(event.key)) {
229
+ if (!current || current.getAttribute('aria-disabled') === 'true') return;
230
+ event.preventDefault();
231
+ (current as HTMLElement).click();
232
+ return;
233
+ }
234
+ const move = rovingMove(event.key, { orientation: 'vertical', homeEnd: true });
235
+ if (move === null) return;
236
+ event.preventDefault();
237
+ rovingTarget(menuRows(panel), current, move, true)?.focus();
238
+ };
239
+ panel.addEventListener('keydown', onKeyDown);
240
+ return () => panel.removeEventListener('keydown', onKeyDown);
241
+ }, [panel, open]);
242
+ }
@@ -51,7 +51,10 @@ import {
51
51
  MENU_SUB_SIDE_OFFSET,
52
52
  ROW_ICON_SIZE,
53
53
  } from './constants';
54
+ import { useMenuSurface } from './context';
55
+ import { pushFloatingEscape } from './escape-stack';
54
56
  import { FloatingPanel } from './FloatingPanel';
57
+ import { hostElement, MENU_ROW_SELECTOR, useMenuPanelKeys } from './menu-keyboard';
55
58
  import { cx, MenuRowChevron, MenuRowShell, splitChildren, SUB_TRIGGER_CLASS } from './shared';
56
59
  import type {
57
60
  FloatingAnchor,
@@ -119,8 +122,7 @@ function isHoverPointer(event: Event): boolean {
119
122
  }
120
123
 
121
124
  /** Every role a menu ROW can carry — the rows a pointer can actually land on. */
122
- const MENU_ITEM_SELECTOR =
123
- '[role="menuitem"], [role="menuitemcheckbox"], [role="menuitemradio"], [role="checkbox"], [role="radio"]';
125
+ const MENU_ITEM_SELECTOR = MENU_ROW_SELECTOR;
124
126
 
125
127
  /**
126
128
  * Did the pointer leave for another ROW, rather than for the gap this sub's
@@ -546,22 +548,25 @@ export function createFlyoutMenuSub(prefix: string): MenuSubParts {
546
548
  };
547
549
  }, [node, sub]);
548
550
 
549
- // Escape, in the CAPTURE phase with `stopImmediatePropagation`. Every open
550
- // `FloatingPanel` has a bubble-phase `keydown` listener on `document`, and
551
- // `stopPropagation` does not stop a sibling listener on the same node — so
552
- // without this the sub and its parent menu would both close on one press.
553
- // Capture runs before bubble whatever the registration order, which is what
554
- // makes "innermost first" hold rather than "whichever mounted first".
551
+ // Escape closes this flyout and leaves the menu open. The flyout's panel is
552
+ // `dismissible={false}` (a press outside it is the parent's business), so it
553
+ // takes its own entry on the escape stack — pushed after the parent's, so it
554
+ // is the one Escape reaches first (`escape-stack.ts`). This used to be a
555
+ // document CAPTURE listener with `stopImmediatePropagation`, which also took
556
+ // Escape away from any field inside the flyout.
557
+ const { open: subOpen, closeAndRefocus } = sub;
558
+ const closeRef = useRef(closeAndRefocus);
559
+ closeRef.current = closeAndRefocus;
555
560
  useEffect(() => {
556
- if (!sub.open || typeof document === 'undefined') return;
557
- const onKeyDown = (event: KeyboardEvent) => {
558
- if (event.key !== 'Escape') return;
559
- event.stopImmediatePropagation();
560
- sub.closeAndRefocus();
561
- };
562
- document.addEventListener('keydown', onKeyDown, true);
563
- return () => document.removeEventListener('keydown', onKeyDown, true);
564
- }, [sub]);
561
+ if (!subOpen || typeof document === 'undefined') return undefined;
562
+ return pushFloatingEscape(() => closeRef.current());
563
+ }, [subOpen]);
564
+
565
+ // Arrows (wrapping), Home/End, Space and Tab among the flyout's own rows —
566
+ // the same keys as the menu it flew out of (`menu-keyboard.ts`). Tab closes
567
+ // the WHOLE menu, not just this flyout: the menu is not in the tab order.
568
+ const surface = useMenuSurface();
569
+ useMenuPanelKeys(hostElement(node), { open: sub.open, onTab: surface.close });
565
570
 
566
571
  // Move focus onto the panel once it has been placed, so Right genuinely
567
572
  // ENTERS the submenu rather than only opening it.
@@ -19,6 +19,7 @@
19
19
  */
20
20
  import type { GestureResponderEvent, StyleProp, TextStyle, View, ViewStyle } from 'react-native';
21
21
 
22
+ import type { MenuFocusIntent } from './menu-keyboard';
22
23
  import type { WebAriaProps } from '../styles/styled-primitives';
23
24
 
24
25
  /**
@@ -32,6 +33,11 @@ export interface OverlayShellContextValue {
32
33
  setOpen: (next: boolean) => void;
33
34
  /** The trigger wrapper. Measured by the web forks, unused on native. */
34
35
  anchorRef: React.RefObject<View | null>;
36
+ /**
37
+ * Web menus only: where a keyboard open lands focus, handed from the trigger
38
+ * to the panel (`menu-keyboard.ts`). Absent on native and on `Popover`.
39
+ */
40
+ focusIntent?: MenuFocusIntent;
35
41
  }
36
42
 
37
43
  /**
@@ -129,6 +135,11 @@ export interface FloatingPanelProps extends FloatingPositionProps {
129
135
  * panel inline (`popover/surface.ts`) and passes it as `style`.
130
136
  */
131
137
  surface?: 'popover' | 'menu' | 'listbox';
138
+ /**
139
+ * Receives the panel's own node as it mounts and unmounts — for a family that
140
+ * attaches keyboard handling to the rows inside it (`menu-keyboard.ts`).
141
+ */
142
+ panelRef?: (node: View | null) => void;
132
143
  }
133
144
 
134
145
  /**
@@ -1,23 +1,8 @@
1
- // Web variant of the `./fonts` barrel.
2
- //
3
- // Every re-export below that has a platform fork names its `.web` source
4
- // OUTRIGHT rather than letting the bundler pick. That is deliberate: web
5
- // bundlers are not required to resolve `.web` extensions (Vite does not, out
6
- // of the box), so an extensionless specifier here would quietly fall through
7
- // to the default file.
8
- //
9
- // - `./apply-font-faces.web` performs the real `@font-face` injection against
10
- // the `.woff2` URLs the consuming bundler emits (see `font-urls.web.ts`);
11
- // the default `./apply-font-faces` is a no-op stub for native.
12
- // - `./font-assets.web` is an empty map. The native map is built from Metro
13
- // asset `require()` calls, and importing it from an ES module throws
14
- // `ReferenceError: require is not defined` during module evaluation — which
15
- // white-screens the consumer before React mounts. Naming the `.web` file
16
- // here is what keeps it out of the web graph.
17
- //
18
- // Web bundlers select this file via the `"browser"` condition in
19
- // `package.json`'s `exports['./fonts']`; native bundlers fall through to
20
- // `./index.ts` via the `"react-native"` condition.
1
+ // AUTO-GENERATED by scripts/generate-platform-exports.mjs — DO NOT EDIT.
2
+ // Source of truth: src/fonts/index.ts.
3
+ // Re-run `bun run generate:exports` (or any `bun run build`) after
4
+ // changing that barrel or the set of web-forked subpaths.
5
+
21
6
  export { fontFamilies, fontCssVars } from './tokens';
22
7
  export type { FontFamilyName } from './tokens';
23
8
  export { applyFontFaces } from './apply-font-faces.web';
@@ -1,3 +1,12 @@
1
+ /**
2
+ * `FrostedIconButton` — WEB: a real HTML `<button>` frosted by a real CSS
3
+ * `backdrop-filter`.
4
+ *
5
+ * The native fork frosts via `expo-blur`'s `BlurView`. Forking the file rather
6
+ * than branching inside one is what keeps that import out of the web graph
7
+ * entirely — `expo-blur` is an optional peer, and a web bundler that resolves
8
+ * it at all is a build a consumer did not ask for.
9
+ */
1
10
  import { useBloomAppearance } from '../appearance';
2
11
  import { resolveBloomColors } from '../appearance/colors';
3
12
  import React, {
@@ -1,9 +1,7 @@
1
- // Web variant of the `./frosted-icon-button` barrel.
2
- //
3
- // The default barrel (`./index.ts`) re-exports the React Native implementation,
4
- // which frosts via `expo-blur`'s `BlurView`. The web fork (`./FrostedIconButton.web`)
5
- // renders a real HTML `<button>` and frosts via a real CSS `backdrop-filter` —
6
- // no `expo-blur` import ever reaches a web bundler. Web bundlers select this
7
- // file via the `"browser"` export condition in `package.json`.
1
+ // AUTO-GENERATED by scripts/generate-platform-exports.mjs — DO NOT EDIT.
2
+ // Source of truth: src/frosted-icon-button/index.ts.
3
+ // Re-run `bun run generate:exports` (or any `bun run build`) after
4
+ // changing that barrel or the set of web-forked subpaths.
5
+
8
6
  export { FrostedIconButton } from './FrostedIconButton.web';
9
7
  export type { FrostedIconButtonProps, FrostedIconButtonSize } from './types';