@oxy.so/bloom 4.5.0 → 4.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (614) 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/seed-scope/index.web.js.map +1 -1
  136. package/lib/commonjs/tooltip/index.web.js.map +1 -1
  137. package/lib/module/agent-chat/index.web.js +5 -3
  138. package/lib/module/agent-chat/index.web.js.map +1 -1
  139. package/lib/module/ai-chat/index.web.js +5 -2
  140. package/lib/module/ai-chat/index.web.js.map +1 -1
  141. package/lib/module/alert-dialog/index.web.js +10 -1
  142. package/lib/module/alert-dialog/index.web.js.map +1 -1
  143. package/lib/module/avatar-group/index.web.js +5 -0
  144. package/lib/module/avatar-group/index.web.js.map +1 -1
  145. package/lib/module/bottom-sheet/index.web.js +5 -0
  146. package/lib/module/bottom-sheet/index.web.js.map +1 -1
  147. package/lib/module/code/index.js +1 -0
  148. package/lib/module/code/index.js.map +1 -1
  149. package/lib/module/command/index.web.js +5 -0
  150. package/lib/module/command/index.web.js.map +1 -1
  151. package/lib/module/composer-loader/ComposerLoader.web.js +8 -0
  152. package/lib/module/composer-loader/ComposerLoader.web.js.map +1 -1
  153. package/lib/module/composer-loader/index.web.js +5 -2
  154. package/lib/module/composer-loader/index.web.js.map +1 -1
  155. package/lib/module/composer-panel/index.web.js +5 -3
  156. package/lib/module/composer-panel/index.web.js.map +1 -1
  157. package/lib/module/connection-dots/index.web.js +5 -0
  158. package/lib/module/connection-dots/index.web.js.map +1 -1
  159. package/lib/module/connection-status/index.web.js +5 -0
  160. package/lib/module/connection-status/index.web.js.map +1 -1
  161. package/lib/module/content-panel/index.web.js +5 -0
  162. package/lib/module/content-panel/index.web.js.map +1 -1
  163. package/lib/module/context-menu/ContextMenu.web.js +22 -4
  164. package/lib/module/context-menu/ContextMenu.web.js.map +1 -1
  165. package/lib/module/context-menu/context.js.map +1 -1
  166. package/lib/module/context-menu/index.web.js +5 -0
  167. package/lib/module/context-menu/index.web.js.map +1 -1
  168. package/lib/module/dialog/Dialog.web.js +13 -0
  169. package/lib/module/dialog/Dialog.web.js.map +1 -1
  170. package/lib/module/dialog/index.web.js +7 -11
  171. package/lib/module/dialog/index.web.js.map +1 -1
  172. package/lib/module/dropdown-menu/DropdownMenu.web.js +23 -3
  173. package/lib/module/dropdown-menu/DropdownMenu.web.js.map +1 -1
  174. package/lib/module/dropdown-menu/index.web.js +5 -0
  175. package/lib/module/dropdown-menu/index.web.js.map +1 -1
  176. package/lib/module/floating/FloatingPanel.js +42 -33
  177. package/lib/module/floating/FloatingPanel.js.map +1 -1
  178. package/lib/module/floating/escape-stack.js +85 -0
  179. package/lib/module/floating/escape-stack.js.map +1 -0
  180. package/lib/module/floating/menu-keyboard.js +227 -0
  181. package/lib/module/floating/menu-keyboard.js.map +1 -0
  182. package/lib/module/floating/menu-sub-flyout.js +28 -16
  183. package/lib/module/floating/menu-sub-flyout.js.map +1 -1
  184. package/lib/module/fonts/index.web.js +5 -20
  185. package/lib/module/fonts/index.web.js.map +1 -1
  186. package/lib/module/frosted-icon-button/FrostedIconButton.web.js +9 -0
  187. package/lib/module/frosted-icon-button/FrostedIconButton.web.js.map +1 -1
  188. package/lib/module/frosted-icon-button/index.web.js +5 -7
  189. package/lib/module/frosted-icon-button/index.web.js.map +1 -1
  190. package/lib/module/hooks/roving-focus.js +181 -0
  191. package/lib/module/hooks/roving-focus.js.map +1 -0
  192. package/lib/module/hover-card/index.web.js +5 -0
  193. package/lib/module/hover-card/index.web.js.map +1 -1
  194. package/lib/module/icons/remix/RiBookReadLine.js +9 -0
  195. package/lib/module/icons/remix/RiBookReadLine.js.map +1 -0
  196. package/lib/module/icons/remix/RiBugLine.js +9 -0
  197. package/lib/module/icons/remix/RiBugLine.js.map +1 -0
  198. package/lib/module/icons/remix/RiChat1Line.js +9 -0
  199. package/lib/module/icons/remix/RiChat1Line.js.map +1 -0
  200. package/lib/module/icons/remix/RiCloudLine.js +9 -0
  201. package/lib/module/icons/remix/RiCloudLine.js.map +1 -0
  202. package/lib/module/icons/remix/RiCodeLine.js +9 -0
  203. package/lib/module/icons/remix/RiCodeLine.js.map +1 -0
  204. package/lib/module/icons/remix/RiCpuLine.js +9 -0
  205. package/lib/module/icons/remix/RiCpuLine.js.map +1 -0
  206. package/lib/module/icons/remix/RiFloodLine.js +9 -0
  207. package/lib/module/icons/remix/RiFloodLine.js.map +1 -0
  208. package/lib/module/icons/remix/RiLockUnlockLine.js +9 -0
  209. package/lib/module/icons/remix/RiLockUnlockLine.js.map +1 -0
  210. package/lib/module/icons/remix/RiMoneyDollarCircleLine.js +9 -0
  211. package/lib/module/icons/remix/RiMoneyDollarCircleLine.js.map +1 -0
  212. package/lib/module/icons/remix/RiPlayCircleLine.js +9 -0
  213. package/lib/module/icons/remix/RiPlayCircleLine.js.map +1 -0
  214. package/lib/module/icons/remix/RiRocket2Line.js +9 -0
  215. package/lib/module/icons/remix/RiRocket2Line.js.map +1 -0
  216. package/lib/module/icons/remix/RiServerLine.js +9 -0
  217. package/lib/module/icons/remix/RiServerLine.js.map +1 -0
  218. package/lib/module/icons/remix/RiShareBoxLine.js +9 -0
  219. package/lib/module/icons/remix/RiShareBoxLine.js.map +1 -0
  220. package/lib/module/icons/remix/RiTv2Line.js +9 -0
  221. package/lib/module/icons/remix/RiTv2Line.js.map +1 -0
  222. package/lib/module/icons/remix/index.js +14 -0
  223. package/lib/module/icons/remix/index.js.map +1 -1
  224. package/lib/module/list/index.web.js +5 -0
  225. package/lib/module/list/index.web.js.map +1 -1
  226. package/lib/module/loading/Loading.js +17 -155
  227. package/lib/module/loading/Loading.js.map +1 -1
  228. package/lib/module/loading/Loading.web.js +19 -155
  229. package/lib/module/loading/Loading.web.js.map +1 -1
  230. package/lib/module/loading/LoadingBase.js +194 -0
  231. package/lib/module/loading/LoadingBase.js.map +1 -0
  232. package/lib/module/loading/index.web.js +5 -13
  233. package/lib/module/loading/index.web.js.map +1 -1
  234. package/lib/module/media-flight/index.web.js +5 -9
  235. package/lib/module/media-flight/index.web.js.map +1 -1
  236. package/lib/module/menubar/Menubar.js +15 -122
  237. package/lib/module/menubar/Menubar.js.map +1 -1
  238. package/lib/module/menubar/Menubar.web.js +18 -114
  239. package/lib/module/menubar/Menubar.web.js.map +1 -1
  240. package/lib/module/menubar/MenubarBase.js +146 -0
  241. package/lib/module/menubar/MenubarBase.js.map +1 -0
  242. package/lib/module/menubar/index.web.js +5 -0
  243. package/lib/module/menubar/index.web.js.map +1 -1
  244. package/lib/module/motion/index.web.js +5 -5
  245. package/lib/module/motion/index.web.js.map +1 -1
  246. package/lib/module/popover/index.web.js +5 -0
  247. package/lib/module/popover/index.web.js.map +1 -1
  248. package/lib/module/popover/parts.js +70 -12
  249. package/lib/module/popover/parts.js.map +1 -1
  250. package/lib/module/popover/surface.js +39 -13
  251. package/lib/module/popover/surface.js.map +1 -1
  252. package/lib/module/portal/index.web.js +6 -1
  253. package/lib/module/portal/index.web.js.map +1 -1
  254. package/lib/module/progressive-blur/index.web.js +5 -0
  255. package/lib/module/progressive-blur/index.web.js.map +1 -1
  256. package/lib/module/scroll/index.web.js +5 -0
  257. package/lib/module/scroll/index.web.js.map +1 -1
  258. package/lib/module/segmented-control/SegmentedControl.js +36 -1
  259. package/lib/module/segmented-control/SegmentedControl.js.map +1 -1
  260. package/lib/module/select/Select.js +5 -77
  261. package/lib/module/select/Select.js.map +1 -1
  262. package/lib/module/select/Select.web.js +147 -82
  263. package/lib/module/select/Select.web.js.map +1 -1
  264. package/lib/module/select/index.js +2 -2
  265. package/lib/module/select/index.js.map +1 -1
  266. package/lib/module/select/index.web.js +7 -2
  267. package/lib/module/select/index.web.js.map +1 -1
  268. package/lib/module/select/shared.js +106 -6
  269. package/lib/module/select/shared.js.map +1 -1
  270. package/lib/module/sidebar/SidebarTeamMenu.js +2 -2
  271. package/lib/module/sidebar/SidebarTeamMenu.js.map +1 -1
  272. package/lib/module/sidebar/SidebarUserMenu.js +2 -2
  273. package/lib/module/sidebar/SidebarUserMenu.js.map +1 -1
  274. package/lib/module/sidebar/parts.js +8 -8
  275. package/lib/module/sidebar/parts.js.map +1 -1
  276. package/lib/module/surfaces/SurfaceHost.js +6 -0
  277. package/lib/module/surfaces/SurfaceHost.js.map +1 -1
  278. package/lib/module/surfaces/index.web.js +14 -4
  279. package/lib/module/surfaces/index.web.js.map +1 -1
  280. package/lib/module/tab-bar/index.web.js +13 -10
  281. package/lib/module/tab-bar/index.web.js.map +1 -1
  282. package/lib/module/tabs/Tabs.js +49 -2
  283. package/lib/module/tabs/Tabs.js.map +1 -1
  284. package/lib/module/theme/color-scope/index.web.js +5 -0
  285. package/lib/module/theme/color-scope/index.web.js.map +1 -1
  286. package/lib/module/theme/seed-scope/index.web.js +5 -0
  287. package/lib/module/theme/seed-scope/index.web.js.map +1 -1
  288. package/lib/module/tooltip/index.web.js +5 -0
  289. package/lib/module/tooltip/index.web.js.map +1 -1
  290. package/lib/typescript/commonjs/agent-chat/index.web.d.ts.map +1 -1
  291. package/lib/typescript/commonjs/ai-chat/index.web.d.ts.map +1 -1
  292. package/lib/typescript/commonjs/alert-dialog/index.web.d.ts +5 -1
  293. package/lib/typescript/commonjs/alert-dialog/index.web.d.ts.map +1 -1
  294. package/lib/typescript/commonjs/avatar-group/index.web.d.ts.map +1 -1
  295. package/lib/typescript/commonjs/bottom-sheet/index.web.d.ts.map +1 -1
  296. package/lib/typescript/commonjs/code/index.d.ts +2 -0
  297. package/lib/typescript/commonjs/code/index.d.ts.map +1 -1
  298. package/lib/typescript/commonjs/command/index.web.d.ts.map +1 -1
  299. package/lib/typescript/commonjs/composer-loader/ComposerLoader.web.d.ts +8 -0
  300. package/lib/typescript/commonjs/composer-loader/ComposerLoader.web.d.ts.map +1 -1
  301. package/lib/typescript/commonjs/composer-loader/index.web.d.ts.map +1 -1
  302. package/lib/typescript/commonjs/composer-panel/index.web.d.ts.map +1 -1
  303. package/lib/typescript/commonjs/connection-dots/index.web.d.ts.map +1 -1
  304. package/lib/typescript/commonjs/connection-status/index.web.d.ts.map +1 -1
  305. package/lib/typescript/commonjs/content-panel/index.web.d.ts.map +1 -1
  306. package/lib/typescript/commonjs/context-menu/ContextMenu.web.d.ts.map +1 -1
  307. package/lib/typescript/commonjs/context-menu/context.d.ts +3 -0
  308. package/lib/typescript/commonjs/context-menu/context.d.ts.map +1 -1
  309. package/lib/typescript/commonjs/context-menu/index.web.d.ts.map +1 -1
  310. package/lib/typescript/commonjs/dialog/Dialog.web.d.ts.map +1 -1
  311. package/lib/typescript/commonjs/dialog/index.web.d.ts +2 -1
  312. package/lib/typescript/commonjs/dialog/index.web.d.ts.map +1 -1
  313. package/lib/typescript/commonjs/dropdown-menu/DropdownMenu.web.d.ts.map +1 -1
  314. package/lib/typescript/commonjs/dropdown-menu/index.web.d.ts.map +1 -1
  315. package/lib/typescript/commonjs/floating/FloatingPanel.d.ts +1 -1
  316. package/lib/typescript/commonjs/floating/FloatingPanel.d.ts.map +1 -1
  317. package/lib/typescript/commonjs/floating/escape-stack.d.ts +55 -0
  318. package/lib/typescript/commonjs/floating/escape-stack.d.ts.map +1 -0
  319. package/lib/typescript/commonjs/floating/menu-keyboard.d.ts +57 -0
  320. package/lib/typescript/commonjs/floating/menu-keyboard.d.ts.map +1 -0
  321. package/lib/typescript/commonjs/floating/menu-sub-flyout.d.ts.map +1 -1
  322. package/lib/typescript/commonjs/floating/types.d.ts +11 -0
  323. package/lib/typescript/commonjs/floating/types.d.ts.map +1 -1
  324. package/lib/typescript/commonjs/fonts/index.web.d.ts.map +1 -1
  325. package/lib/typescript/commonjs/frosted-icon-button/FrostedIconButton.web.d.ts.map +1 -1
  326. package/lib/typescript/commonjs/frosted-icon-button/index.web.d.ts.map +1 -1
  327. package/lib/typescript/commonjs/hooks/roving-focus.d.ts +66 -0
  328. package/lib/typescript/commonjs/hooks/roving-focus.d.ts.map +1 -0
  329. package/lib/typescript/commonjs/hover-card/index.web.d.ts.map +1 -1
  330. package/lib/typescript/commonjs/icons/remix/RiBookReadLine.d.ts +8 -0
  331. package/lib/typescript/commonjs/icons/remix/RiBookReadLine.d.ts.map +1 -0
  332. package/lib/typescript/commonjs/icons/remix/RiBugLine.d.ts +8 -0
  333. package/lib/typescript/commonjs/icons/remix/RiBugLine.d.ts.map +1 -0
  334. package/lib/typescript/commonjs/icons/remix/RiChat1Line.d.ts +8 -0
  335. package/lib/typescript/commonjs/icons/remix/RiChat1Line.d.ts.map +1 -0
  336. package/lib/typescript/commonjs/icons/remix/RiCloudLine.d.ts +8 -0
  337. package/lib/typescript/commonjs/icons/remix/RiCloudLine.d.ts.map +1 -0
  338. package/lib/typescript/commonjs/icons/remix/RiCodeLine.d.ts +8 -0
  339. package/lib/typescript/commonjs/icons/remix/RiCodeLine.d.ts.map +1 -0
  340. package/lib/typescript/commonjs/icons/remix/RiCpuLine.d.ts +8 -0
  341. package/lib/typescript/commonjs/icons/remix/RiCpuLine.d.ts.map +1 -0
  342. package/lib/typescript/commonjs/icons/remix/RiFloodLine.d.ts +8 -0
  343. package/lib/typescript/commonjs/icons/remix/RiFloodLine.d.ts.map +1 -0
  344. package/lib/typescript/commonjs/icons/remix/RiLockUnlockLine.d.ts +8 -0
  345. package/lib/typescript/commonjs/icons/remix/RiLockUnlockLine.d.ts.map +1 -0
  346. package/lib/typescript/commonjs/icons/remix/RiMoneyDollarCircleLine.d.ts +8 -0
  347. package/lib/typescript/commonjs/icons/remix/RiMoneyDollarCircleLine.d.ts.map +1 -0
  348. package/lib/typescript/commonjs/icons/remix/RiPlayCircleLine.d.ts +8 -0
  349. package/lib/typescript/commonjs/icons/remix/RiPlayCircleLine.d.ts.map +1 -0
  350. package/lib/typescript/commonjs/icons/remix/RiRocket2Line.d.ts +8 -0
  351. package/lib/typescript/commonjs/icons/remix/RiRocket2Line.d.ts.map +1 -0
  352. package/lib/typescript/commonjs/icons/remix/RiServerLine.d.ts +8 -0
  353. package/lib/typescript/commonjs/icons/remix/RiServerLine.d.ts.map +1 -0
  354. package/lib/typescript/commonjs/icons/remix/RiShareBoxLine.d.ts +8 -0
  355. package/lib/typescript/commonjs/icons/remix/RiShareBoxLine.d.ts.map +1 -0
  356. package/lib/typescript/commonjs/icons/remix/RiTv2Line.d.ts +8 -0
  357. package/lib/typescript/commonjs/icons/remix/RiTv2Line.d.ts.map +1 -0
  358. package/lib/typescript/commonjs/icons/remix/index.d.ts +14 -0
  359. package/lib/typescript/commonjs/icons/remix/index.d.ts.map +1 -1
  360. package/lib/typescript/commonjs/list/index.web.d.ts.map +1 -1
  361. package/lib/typescript/commonjs/loading/Loading.d.ts +8 -2
  362. package/lib/typescript/commonjs/loading/Loading.d.ts.map +1 -1
  363. package/lib/typescript/commonjs/loading/Loading.web.d.ts +10 -2
  364. package/lib/typescript/commonjs/loading/Loading.web.d.ts.map +1 -1
  365. package/lib/typescript/commonjs/loading/LoadingBase.d.ts +64 -0
  366. package/lib/typescript/commonjs/loading/LoadingBase.d.ts.map +1 -0
  367. package/lib/typescript/commonjs/loading/index.web.d.ts.map +1 -1
  368. package/lib/typescript/commonjs/media-flight/index.web.d.ts +0 -9
  369. package/lib/typescript/commonjs/media-flight/index.web.d.ts.map +1 -1
  370. package/lib/typescript/commonjs/menubar/Menubar.d.ts +14 -9
  371. package/lib/typescript/commonjs/menubar/Menubar.d.ts.map +1 -1
  372. package/lib/typescript/commonjs/menubar/Menubar.web.d.ts +8 -6
  373. package/lib/typescript/commonjs/menubar/Menubar.web.d.ts.map +1 -1
  374. package/lib/typescript/commonjs/menubar/MenubarBase.d.ts +5 -0
  375. package/lib/typescript/commonjs/menubar/MenubarBase.d.ts.map +1 -0
  376. package/lib/typescript/commonjs/menubar/index.web.d.ts.map +1 -1
  377. package/lib/typescript/commonjs/motion/index.web.d.ts +0 -5
  378. package/lib/typescript/commonjs/motion/index.web.d.ts.map +1 -1
  379. package/lib/typescript/commonjs/popover/index.web.d.ts.map +1 -1
  380. package/lib/typescript/commonjs/popover/parts.d.ts.map +1 -1
  381. package/lib/typescript/commonjs/popover/surface.d.ts +15 -5
  382. package/lib/typescript/commonjs/popover/surface.d.ts.map +1 -1
  383. package/lib/typescript/commonjs/portal/index.web.d.ts +1 -1
  384. package/lib/typescript/commonjs/portal/index.web.d.ts.map +1 -1
  385. package/lib/typescript/commonjs/progressive-blur/index.web.d.ts.map +1 -1
  386. package/lib/typescript/commonjs/scroll/index.web.d.ts.map +1 -1
  387. package/lib/typescript/commonjs/segmented-control/SegmentedControl.d.ts.map +1 -1
  388. package/lib/typescript/commonjs/select/Select.d.ts +2 -4
  389. package/lib/typescript/commonjs/select/Select.d.ts.map +1 -1
  390. package/lib/typescript/commonjs/select/Select.web.d.ts +2 -4
  391. package/lib/typescript/commonjs/select/Select.web.d.ts.map +1 -1
  392. package/lib/typescript/commonjs/select/index.d.ts +2 -2
  393. package/lib/typescript/commonjs/select/index.d.ts.map +1 -1
  394. package/lib/typescript/commonjs/select/index.web.d.ts +2 -2
  395. package/lib/typescript/commonjs/select/index.web.d.ts.map +1 -1
  396. package/lib/typescript/commonjs/select/shared.d.ts +52 -5
  397. package/lib/typescript/commonjs/select/shared.d.ts.map +1 -1
  398. package/lib/typescript/commonjs/select/types.d.ts +6 -0
  399. package/lib/typescript/commonjs/select/types.d.ts.map +1 -1
  400. package/lib/typescript/commonjs/sidebar/parts.d.ts +8 -2
  401. package/lib/typescript/commonjs/sidebar/parts.d.ts.map +1 -1
  402. package/lib/typescript/commonjs/surfaces/SurfaceHost.d.ts.map +1 -1
  403. package/lib/typescript/commonjs/surfaces/index.web.d.ts +9 -4
  404. package/lib/typescript/commonjs/surfaces/index.web.d.ts.map +1 -1
  405. package/lib/typescript/commonjs/tab-bar/index.web.d.ts.map +1 -1
  406. package/lib/typescript/commonjs/tabs/Tabs.d.ts.map +1 -1
  407. package/lib/typescript/commonjs/tabs/types.d.ts +6 -0
  408. package/lib/typescript/commonjs/tabs/types.d.ts.map +1 -1
  409. package/lib/typescript/commonjs/theme/color-scope/index.web.d.ts.map +1 -1
  410. package/lib/typescript/commonjs/theme/seed-scope/index.web.d.ts.map +1 -1
  411. package/lib/typescript/commonjs/tooltip/index.web.d.ts.map +1 -1
  412. package/lib/typescript/module/agent-chat/index.web.d.ts.map +1 -1
  413. package/lib/typescript/module/ai-chat/index.web.d.ts.map +1 -1
  414. package/lib/typescript/module/alert-dialog/index.web.d.ts +5 -1
  415. package/lib/typescript/module/alert-dialog/index.web.d.ts.map +1 -1
  416. package/lib/typescript/module/avatar-group/index.web.d.ts.map +1 -1
  417. package/lib/typescript/module/bottom-sheet/index.web.d.ts.map +1 -1
  418. package/lib/typescript/module/code/index.d.ts +2 -0
  419. package/lib/typescript/module/code/index.d.ts.map +1 -1
  420. package/lib/typescript/module/command/index.web.d.ts.map +1 -1
  421. package/lib/typescript/module/composer-loader/ComposerLoader.web.d.ts +8 -0
  422. package/lib/typescript/module/composer-loader/ComposerLoader.web.d.ts.map +1 -1
  423. package/lib/typescript/module/composer-loader/index.web.d.ts.map +1 -1
  424. package/lib/typescript/module/composer-panel/index.web.d.ts.map +1 -1
  425. package/lib/typescript/module/connection-dots/index.web.d.ts.map +1 -1
  426. package/lib/typescript/module/connection-status/index.web.d.ts.map +1 -1
  427. package/lib/typescript/module/content-panel/index.web.d.ts.map +1 -1
  428. package/lib/typescript/module/context-menu/ContextMenu.web.d.ts.map +1 -1
  429. package/lib/typescript/module/context-menu/context.d.ts +3 -0
  430. package/lib/typescript/module/context-menu/context.d.ts.map +1 -1
  431. package/lib/typescript/module/context-menu/index.web.d.ts.map +1 -1
  432. package/lib/typescript/module/dialog/Dialog.web.d.ts.map +1 -1
  433. package/lib/typescript/module/dialog/index.web.d.ts +2 -1
  434. package/lib/typescript/module/dialog/index.web.d.ts.map +1 -1
  435. package/lib/typescript/module/dropdown-menu/DropdownMenu.web.d.ts.map +1 -1
  436. package/lib/typescript/module/dropdown-menu/index.web.d.ts.map +1 -1
  437. package/lib/typescript/module/floating/FloatingPanel.d.ts +1 -1
  438. package/lib/typescript/module/floating/FloatingPanel.d.ts.map +1 -1
  439. package/lib/typescript/module/floating/escape-stack.d.ts +55 -0
  440. package/lib/typescript/module/floating/escape-stack.d.ts.map +1 -0
  441. package/lib/typescript/module/floating/menu-keyboard.d.ts +57 -0
  442. package/lib/typescript/module/floating/menu-keyboard.d.ts.map +1 -0
  443. package/lib/typescript/module/floating/menu-sub-flyout.d.ts.map +1 -1
  444. package/lib/typescript/module/floating/types.d.ts +11 -0
  445. package/lib/typescript/module/floating/types.d.ts.map +1 -1
  446. package/lib/typescript/module/fonts/index.web.d.ts.map +1 -1
  447. package/lib/typescript/module/frosted-icon-button/FrostedIconButton.web.d.ts.map +1 -1
  448. package/lib/typescript/module/frosted-icon-button/index.web.d.ts.map +1 -1
  449. package/lib/typescript/module/hooks/roving-focus.d.ts +66 -0
  450. package/lib/typescript/module/hooks/roving-focus.d.ts.map +1 -0
  451. package/lib/typescript/module/hover-card/index.web.d.ts.map +1 -1
  452. package/lib/typescript/module/icons/remix/RiBookReadLine.d.ts +8 -0
  453. package/lib/typescript/module/icons/remix/RiBookReadLine.d.ts.map +1 -0
  454. package/lib/typescript/module/icons/remix/RiBugLine.d.ts +8 -0
  455. package/lib/typescript/module/icons/remix/RiBugLine.d.ts.map +1 -0
  456. package/lib/typescript/module/icons/remix/RiChat1Line.d.ts +8 -0
  457. package/lib/typescript/module/icons/remix/RiChat1Line.d.ts.map +1 -0
  458. package/lib/typescript/module/icons/remix/RiCloudLine.d.ts +8 -0
  459. package/lib/typescript/module/icons/remix/RiCloudLine.d.ts.map +1 -0
  460. package/lib/typescript/module/icons/remix/RiCodeLine.d.ts +8 -0
  461. package/lib/typescript/module/icons/remix/RiCodeLine.d.ts.map +1 -0
  462. package/lib/typescript/module/icons/remix/RiCpuLine.d.ts +8 -0
  463. package/lib/typescript/module/icons/remix/RiCpuLine.d.ts.map +1 -0
  464. package/lib/typescript/module/icons/remix/RiFloodLine.d.ts +8 -0
  465. package/lib/typescript/module/icons/remix/RiFloodLine.d.ts.map +1 -0
  466. package/lib/typescript/module/icons/remix/RiLockUnlockLine.d.ts +8 -0
  467. package/lib/typescript/module/icons/remix/RiLockUnlockLine.d.ts.map +1 -0
  468. package/lib/typescript/module/icons/remix/RiMoneyDollarCircleLine.d.ts +8 -0
  469. package/lib/typescript/module/icons/remix/RiMoneyDollarCircleLine.d.ts.map +1 -0
  470. package/lib/typescript/module/icons/remix/RiPlayCircleLine.d.ts +8 -0
  471. package/lib/typescript/module/icons/remix/RiPlayCircleLine.d.ts.map +1 -0
  472. package/lib/typescript/module/icons/remix/RiRocket2Line.d.ts +8 -0
  473. package/lib/typescript/module/icons/remix/RiRocket2Line.d.ts.map +1 -0
  474. package/lib/typescript/module/icons/remix/RiServerLine.d.ts +8 -0
  475. package/lib/typescript/module/icons/remix/RiServerLine.d.ts.map +1 -0
  476. package/lib/typescript/module/icons/remix/RiShareBoxLine.d.ts +8 -0
  477. package/lib/typescript/module/icons/remix/RiShareBoxLine.d.ts.map +1 -0
  478. package/lib/typescript/module/icons/remix/RiTv2Line.d.ts +8 -0
  479. package/lib/typescript/module/icons/remix/RiTv2Line.d.ts.map +1 -0
  480. package/lib/typescript/module/icons/remix/index.d.ts +14 -0
  481. package/lib/typescript/module/icons/remix/index.d.ts.map +1 -1
  482. package/lib/typescript/module/list/index.web.d.ts.map +1 -1
  483. package/lib/typescript/module/loading/Loading.d.ts +8 -2
  484. package/lib/typescript/module/loading/Loading.d.ts.map +1 -1
  485. package/lib/typescript/module/loading/Loading.web.d.ts +10 -2
  486. package/lib/typescript/module/loading/Loading.web.d.ts.map +1 -1
  487. package/lib/typescript/module/loading/LoadingBase.d.ts +64 -0
  488. package/lib/typescript/module/loading/LoadingBase.d.ts.map +1 -0
  489. package/lib/typescript/module/loading/index.web.d.ts.map +1 -1
  490. package/lib/typescript/module/media-flight/index.web.d.ts +0 -9
  491. package/lib/typescript/module/media-flight/index.web.d.ts.map +1 -1
  492. package/lib/typescript/module/menubar/Menubar.d.ts +14 -9
  493. package/lib/typescript/module/menubar/Menubar.d.ts.map +1 -1
  494. package/lib/typescript/module/menubar/Menubar.web.d.ts +8 -6
  495. package/lib/typescript/module/menubar/Menubar.web.d.ts.map +1 -1
  496. package/lib/typescript/module/menubar/MenubarBase.d.ts +5 -0
  497. package/lib/typescript/module/menubar/MenubarBase.d.ts.map +1 -0
  498. package/lib/typescript/module/menubar/index.web.d.ts.map +1 -1
  499. package/lib/typescript/module/motion/index.web.d.ts +0 -5
  500. package/lib/typescript/module/motion/index.web.d.ts.map +1 -1
  501. package/lib/typescript/module/popover/index.web.d.ts.map +1 -1
  502. package/lib/typescript/module/popover/parts.d.ts.map +1 -1
  503. package/lib/typescript/module/popover/surface.d.ts +15 -5
  504. package/lib/typescript/module/popover/surface.d.ts.map +1 -1
  505. package/lib/typescript/module/portal/index.web.d.ts +1 -1
  506. package/lib/typescript/module/portal/index.web.d.ts.map +1 -1
  507. package/lib/typescript/module/progressive-blur/index.web.d.ts.map +1 -1
  508. package/lib/typescript/module/scroll/index.web.d.ts.map +1 -1
  509. package/lib/typescript/module/segmented-control/SegmentedControl.d.ts.map +1 -1
  510. package/lib/typescript/module/select/Select.d.ts +2 -4
  511. package/lib/typescript/module/select/Select.d.ts.map +1 -1
  512. package/lib/typescript/module/select/Select.web.d.ts +2 -4
  513. package/lib/typescript/module/select/Select.web.d.ts.map +1 -1
  514. package/lib/typescript/module/select/index.d.ts +2 -2
  515. package/lib/typescript/module/select/index.d.ts.map +1 -1
  516. package/lib/typescript/module/select/index.web.d.ts +2 -2
  517. package/lib/typescript/module/select/index.web.d.ts.map +1 -1
  518. package/lib/typescript/module/select/shared.d.ts +52 -5
  519. package/lib/typescript/module/select/shared.d.ts.map +1 -1
  520. package/lib/typescript/module/select/types.d.ts +6 -0
  521. package/lib/typescript/module/select/types.d.ts.map +1 -1
  522. package/lib/typescript/module/sidebar/parts.d.ts +8 -2
  523. package/lib/typescript/module/sidebar/parts.d.ts.map +1 -1
  524. package/lib/typescript/module/surfaces/SurfaceHost.d.ts.map +1 -1
  525. package/lib/typescript/module/surfaces/index.web.d.ts +9 -4
  526. package/lib/typescript/module/surfaces/index.web.d.ts.map +1 -1
  527. package/lib/typescript/module/tab-bar/index.web.d.ts.map +1 -1
  528. package/lib/typescript/module/tabs/Tabs.d.ts.map +1 -1
  529. package/lib/typescript/module/tabs/types.d.ts +6 -0
  530. package/lib/typescript/module/tabs/types.d.ts.map +1 -1
  531. package/lib/typescript/module/theme/color-scope/index.web.d.ts.map +1 -1
  532. package/lib/typescript/module/theme/seed-scope/index.web.d.ts.map +1 -1
  533. package/lib/typescript/module/tooltip/index.web.d.ts.map +1 -1
  534. package/package.json +1 -1
  535. package/src/agent-chat/index.web.ts +5 -3
  536. package/src/ai-chat/index.web.ts +5 -2
  537. package/src/alert-dialog/index.web.ts +10 -1
  538. package/src/avatar-group/index.web.ts +5 -0
  539. package/src/bottom-sheet/index.web.ts +5 -0
  540. package/src/code/index.ts +2 -0
  541. package/src/command/index.web.ts +5 -0
  542. package/src/composer-loader/ComposerLoader.web.tsx +8 -0
  543. package/src/composer-loader/index.web.ts +5 -2
  544. package/src/composer-panel/index.web.ts +5 -3
  545. package/src/connection-dots/index.web.ts +5 -0
  546. package/src/connection-status/index.web.ts +5 -0
  547. package/src/content-panel/index.web.ts +5 -0
  548. package/src/context-menu/ContextMenu.web.tsx +26 -3
  549. package/src/context-menu/context.ts +3 -0
  550. package/src/context-menu/index.web.ts +5 -0
  551. package/src/dialog/Dialog.web.tsx +13 -0
  552. package/src/dialog/index.web.ts +7 -11
  553. package/src/dropdown-menu/DropdownMenu.web.tsx +25 -2
  554. package/src/dropdown-menu/index.web.ts +5 -0
  555. package/src/floating/FloatingPanel.tsx +37 -38
  556. package/src/floating/escape-stack.ts +92 -0
  557. package/src/floating/menu-keyboard.ts +242 -0
  558. package/src/floating/menu-sub-flyout.tsx +22 -17
  559. package/src/floating/types.ts +11 -0
  560. package/src/fonts/index.web.ts +5 -20
  561. package/src/frosted-icon-button/FrostedIconButton.web.tsx +9 -0
  562. package/src/frosted-icon-button/index.web.ts +5 -7
  563. package/src/hooks/roving-focus.ts +204 -0
  564. package/src/hover-card/index.web.ts +5 -0
  565. package/src/icons/remix/RiBookReadLine.tsx +6 -0
  566. package/src/icons/remix/RiBugLine.tsx +6 -0
  567. package/src/icons/remix/RiChat1Line.tsx +6 -0
  568. package/src/icons/remix/RiCloudLine.tsx +6 -0
  569. package/src/icons/remix/RiCodeLine.tsx +6 -0
  570. package/src/icons/remix/RiCpuLine.tsx +6 -0
  571. package/src/icons/remix/RiFloodLine.tsx +6 -0
  572. package/src/icons/remix/RiLockUnlockLine.tsx +6 -0
  573. package/src/icons/remix/RiMoneyDollarCircleLine.tsx +6 -0
  574. package/src/icons/remix/RiPlayCircleLine.tsx +6 -0
  575. package/src/icons/remix/RiRocket2Line.tsx +6 -0
  576. package/src/icons/remix/RiServerLine.tsx +6 -0
  577. package/src/icons/remix/RiShareBoxLine.tsx +6 -0
  578. package/src/icons/remix/RiTv2Line.tsx +6 -0
  579. package/src/icons/remix/index.ts +14 -0
  580. package/src/list/index.web.ts +5 -0
  581. package/src/loading/Loading.tsx +15 -135
  582. package/src/loading/Loading.web.tsx +16 -134
  583. package/src/loading/LoadingBase.tsx +170 -0
  584. package/src/loading/index.web.ts +5 -13
  585. package/src/media-flight/index.web.ts +5 -9
  586. package/src/menubar/Menubar.tsx +16 -147
  587. package/src/menubar/Menubar.web.tsx +15 -138
  588. package/src/menubar/MenubarBase.tsx +170 -0
  589. package/src/menubar/index.web.ts +5 -0
  590. package/src/motion/index.web.ts +5 -5
  591. package/src/popover/index.web.ts +5 -0
  592. package/src/popover/parts.tsx +76 -12
  593. package/src/popover/surface.ts +68 -15
  594. package/src/portal/index.web.ts +6 -1
  595. package/src/progressive-blur/index.web.ts +5 -0
  596. package/src/scroll/index.web.ts +5 -0
  597. package/src/segmented-control/SegmentedControl.tsx +45 -1
  598. package/src/select/Select.tsx +4 -67
  599. package/src/select/Select.web.tsx +133 -69
  600. package/src/select/index.ts +3 -3
  601. package/src/select/index.web.ts +8 -3
  602. package/src/select/shared.tsx +107 -5
  603. package/src/select/types.ts +6 -0
  604. package/src/sidebar/SidebarTeamMenu.tsx +2 -2
  605. package/src/sidebar/SidebarUserMenu.tsx +2 -2
  606. package/src/sidebar/parts.tsx +8 -9
  607. package/src/surfaces/SurfaceHost.tsx +6 -0
  608. package/src/surfaces/index.web.ts +14 -4
  609. package/src/tab-bar/index.web.ts +13 -10
  610. package/src/tabs/Tabs.tsx +65 -1
  611. package/src/tabs/types.ts +6 -0
  612. package/src/theme/color-scope/index.web.ts +5 -0
  613. package/src/theme/seed-scope/index.web.ts +5 -0
  614. package/src/tooltip/index.web.ts +5 -0
@@ -1,160 +1,34 @@
1
1
  /**
2
- * `Menubar` — WEB. The bar is the same row of triggers; each menu is an anchored
3
- * panel from `floating/FloatingPanel` rather than a sheet.
2
+ * `Menubar` — WEB: each menu is an anchored panel from `floating/FloatingPanel`
3
+ * rather than a sheet.
4
+ *
5
+ * The bar, the per-menu state and the trigger are identical on both platforms
6
+ * and live in `MenubarBase`. What forks is this file: the surface a menu opens
7
+ * into, and which sub-menu the rows get — a FLYOUT here, which needs a pointer.
4
8
  *
5
9
  * `align="start"` and the trigger's own width as `minWidth` are what make a
6
10
  * menubar menu hang under its trigger the way a desktop menu bar does, rather
7
11
  * than centring like a popover.
8
12
  */
9
- import React, { useCallback, useMemo, useRef } from 'react';
10
- import type { View as RNView } from 'react-native';
13
+ import React, { useCallback, useMemo, useState } from 'react';
14
+ import type { View } from 'react-native';
11
15
 
12
16
  import {
13
17
  MENUBAR_ALIGN_OFFSET,
14
- MENUBAR_CLASS,
15
18
  MENUBAR_MENU_MIN_WIDTH_CLASS,
16
19
  MENUBAR_SIDE_OFFSET,
17
- MENUBAR_TRIGGER_CLASS,
18
- MENUBAR_TRIGGER_OPEN_CLASS,
19
- MENUBAR_TRIGGER_TEXT_CLASS,
20
- MENU_TRIGGER_POPUP,
21
20
  } from '../floating/constants';
22
21
  import { MenuSurfaceProvider, type MenuSurfaceContextValue } from '../floating/context';
23
22
  import { FloatingPanel } from '../floating/FloatingPanel';
23
+ import { hostElement, useMenuPanelKeys } from '../floating/menu-keyboard';
24
24
  import { createMenuRows } from '../floating/menu-rows';
25
25
  import { createFlyoutMenuSub } from '../floating/menu-sub-flyout';
26
26
  import { cx } from '../floating/shared';
27
- import { TriggerSlot } from '../floating/TriggerSlot';
28
27
  import { useAnchorRect } from '../floating/use-anchor-rect';
29
- import { useControllableState } from '../hooks/use-controllable-state';
30
- import { StyledText, StyledView } from '../styles/styled-primitives';
31
- import { useMenuPalette } from '../floating/menu-palette';
32
- import { menuType } from '../floating/menu-type';
33
- import {
34
- MenubarMenuProvider,
35
- MenubarProvider,
36
- useMenubar,
37
- useMenubarMenu,
38
- } from './context';
39
- import type {
40
- MenubarContentProps,
41
- MenubarMenuProps,
42
- MenubarProps,
43
- MenubarTriggerProps,
44
- } from './types';
45
-
46
- export function Menubar({
47
- children,
48
- value,
49
- defaultValue,
50
- onValueChange,
51
- label = 'Menu bar',
52
- className,
53
- style,
54
- testID,
55
- }: MenubarProps) {
56
- const [openValue, setValue] = useControllableState<string | undefined>({
57
- value,
58
- defaultValue,
59
- onChange: onValueChange,
60
- });
61
- const context = useMemo(() => ({ value: openValue, setValue }), [openValue, setValue]);
62
- const palette = useMenuPalette();
63
- const barPaint = {
64
- backgroundColor: palette.trigger.background,
65
- borderColor: palette.trigger.border,
66
- boxShadow: palette.trigger.shadow,
67
- };
68
-
69
- return (
70
- <MenubarProvider value={context}>
71
- {/* `shadow-s` — the bar is a raised control, not an overlay, so it takes
72
- the lighter of Bloom's two elevation roles. */}
73
- <StyledView
74
- role="menubar"
75
- aria-label={label}
76
- testID={testID}
77
- className={cx(MENUBAR_CLASS, className)}
78
- style={[barPaint, style]}>
79
- {children}
80
- </StyledView>
81
- </MenubarProvider>
82
- );
83
- }
84
-
85
- export function MenubarMenu({ children, value }: MenubarMenuProps) {
86
- const bar = useMenubar();
87
- const anchorRef = useRef<RNView | null>(null);
88
- const { setValue } = bar;
89
-
90
- const context = useMemo(
91
- () => ({
92
- open: bar.value === value,
93
- setOpen: (next: boolean) => setValue(next ? value : undefined),
94
- anchorRef,
95
- }),
96
- [bar.value, value, setValue],
97
- );
28
+ import { useMenubarMenu } from './context';
29
+ import type { MenubarContentProps } from './types';
98
30
 
99
- return <MenubarMenuProvider value={context}>{children}</MenubarMenuProvider>;
100
- }
101
-
102
- export function MenubarTrigger({
103
- children,
104
- asChild,
105
- disabled,
106
- label,
107
- className,
108
- style,
109
- testID,
110
- }: MenubarTriggerProps) {
111
- const menu = useMenubarMenu();
112
- const palette = useMenuPalette();
113
-
114
- // `flex items-center rounded-md px-2 py-1.5`, plus `bg-accent` while its menu
115
- // is open, and `text-sm font-medium` for the label. A menubar trigger is a
116
- // BUTTON with chrome of its own, not a bare hit box — leaving it unstyled is
117
- // why a Bloom menubar read as loose text against a pill-per-menu bar.
118
- // `asChild` still hands the whole thing to the caller.
119
- const trigger = (
120
- <StyledView
121
- className={cx(
122
- MENUBAR_TRIGGER_CLASS,
123
- menu.open && MENUBAR_TRIGGER_OPEN_CLASS,
124
- className,
125
- )}
126
- style={{ backgroundColor: menu.open ? palette.rowHighlight : 'transparent' }}>
127
- {typeof children === 'string' ? (
128
- <StyledText
129
- className={MENUBAR_TRIGGER_TEXT_CLASS}
130
- // `text-body-medium text-text-primary`, in Inter.
131
- style={[menuType('body-medium'), { color: palette.text }]}>
132
- {children}
133
- </StyledText>
134
- ) : (
135
- children
136
- )}
137
- </StyledView>
138
- );
139
-
140
- return (
141
- <TriggerSlot
142
- asChild={asChild}
143
- anchorRef={menu.anchorRef}
144
- style={style}
145
- testID={testID}
146
- handle={{
147
- onPress: () => menu.setOpen(!menu.open),
148
- disabled,
149
- accessibilityLabel: label,
150
- accessibilityRole: 'button',
151
- 'aria-haspopup': MENU_TRIGGER_POPUP,
152
- 'aria-expanded': menu.open,
153
- }}>
154
- {asChild ? children : trigger}
155
- </TriggerSlot>
156
- );
157
- }
31
+ export { Menubar, MenubarMenu, MenubarTrigger } from './MenubarBase';
158
32
 
159
33
  export function MenubarContent({
160
34
  children,
@@ -180,9 +54,12 @@ export function MenubarContent({
180
54
  () => ({ close, presentation: 'dropdown' }),
181
55
  [close],
182
56
  );
57
+ const [panel, setPanel] = useState<View | null>(null);
58
+ useMenuPanelKeys(hostElement(panel), { open: menu.open, onTab: close, intent: menu.focusIntent });
183
59
 
184
60
  return (
185
61
  <FloatingPanel
62
+ panelRef={setPanel}
186
63
  open={menu.open}
187
64
  anchor={anchor}
188
65
  role="menu"
@@ -0,0 +1,170 @@
1
+ /**
2
+ * The three `Menubar` parts that are the SAME on both platforms.
3
+ *
4
+ * A menubar forks in exactly one place — what a menu opens INTO. Native
5
+ * presents the bottom sheet every Bloom overlay resolves to; web anchors a
6
+ * `floating/FloatingPanel` under the trigger. The bar itself, the per-menu
7
+ * state and the trigger are identical, so they live here and each fork
8
+ * re-exports them rather than keeping a second copy that has to be edited
9
+ * twice.
10
+ *
11
+ * NEUTRAL by construction: everything this module reaches (`floating/*`,
12
+ * `hooks/*`, `styles/*`, `./context`, `./types`) is fork-free. That is not a
13
+ * detail — `web-fork-reachability.test.ts` only scans `.web` files, so a
14
+ * neutral module naming a forked target resolves to NATIVE in every bundler
15
+ * that is not Metro and no gate would report it.
16
+ */
17
+ import React, { useMemo, useRef } from 'react';
18
+ import type { View as RNView } from 'react-native';
19
+
20
+ import {
21
+ MENUBAR_CLASS,
22
+ MENUBAR_TRIGGER_CLASS,
23
+ MENUBAR_TRIGGER_OPEN_CLASS,
24
+ MENUBAR_TRIGGER_TEXT_CLASS,
25
+ MENU_TRIGGER_POPUP,
26
+ } from '../floating/constants';
27
+ import { useMenuPalette } from '../floating/menu-palette';
28
+ import { menuType } from '../floating/menu-type';
29
+ import { cx } from '../floating/shared';
30
+ import { TriggerSlot } from '../floating/TriggerSlot';
31
+ import { useMenuFocusIntent, useMenuTriggerKeys } from '../floating/menu-keyboard';
32
+ import { useControllableState } from '../hooks/use-controllable-state';
33
+ import { StyledText, StyledView } from '../styles/styled-primitives';
34
+ import {
35
+ MenubarMenuProvider,
36
+ MenubarProvider,
37
+ useMenubar,
38
+ useMenubarMenu,
39
+ } from './context';
40
+ import type { MenubarMenuProps, MenubarProps, MenubarTriggerProps } from './types';
41
+
42
+ export function Menubar({
43
+ children,
44
+ value,
45
+ defaultValue,
46
+ onValueChange,
47
+ label = 'Menu bar',
48
+ className,
49
+ style,
50
+ testID,
51
+ }: MenubarProps) {
52
+ const [openValue, setValue] = useControllableState<string | undefined>({
53
+ value,
54
+ defaultValue,
55
+ onChange: onValueChange,
56
+ });
57
+ const context = useMemo(() => ({ value: openValue, setValue }), [openValue, setValue]);
58
+ const palette = useMenuPalette();
59
+ const barPaint = {
60
+ backgroundColor: palette.trigger.background,
61
+ borderColor: palette.trigger.border,
62
+ boxShadow: palette.trigger.shadow,
63
+ };
64
+
65
+ return (
66
+ <MenubarProvider value={context}>
67
+ {/* `shadow-s` — the bar is a raised control, not an overlay, so it takes
68
+ the lighter of Bloom's two elevation roles. It reaches WEB through the
69
+ class and NATIVE through `barPaint`, because `design-tokens/shadows`
70
+ is platform-forked and its contract is that a multi-layer
71
+ `box-shadow` is not something to rely on NativeWind translating to an
72
+ RN elevation. On web the two agree, so whichever wins paints the
73
+ same thing. */}
74
+ <StyledView
75
+ role="menubar"
76
+ aria-label={label}
77
+ testID={testID}
78
+ className={cx(MENUBAR_CLASS, className)}
79
+ style={[barPaint, style]}>
80
+ {children}
81
+ </StyledView>
82
+ </MenubarProvider>
83
+ );
84
+ }
85
+
86
+ export function MenubarMenu({ children, value }: MenubarMenuProps) {
87
+ const bar = useMenubar();
88
+ const anchorRef = useRef<RNView | null>(null);
89
+ const { setValue } = bar;
90
+ const focusIntent = useMenuFocusIntent();
91
+
92
+ const context = useMemo(
93
+ () => ({
94
+ open: bar.value === value,
95
+ setOpen: (next: boolean) => setValue(next ? value : undefined),
96
+ anchorRef,
97
+ focusIntent,
98
+ }),
99
+ [bar.value, value, setValue, focusIntent],
100
+ );
101
+
102
+ return <MenubarMenuProvider value={context}>{children}</MenubarMenuProvider>;
103
+ }
104
+
105
+ export function MenubarTrigger({
106
+ children,
107
+ asChild,
108
+ disabled,
109
+ label,
110
+ className,
111
+ style,
112
+ testID,
113
+ }: MenubarTriggerProps) {
114
+ const menu = useMenubarMenu();
115
+ const palette = useMenuPalette();
116
+ // Web: Enter/Space/ArrowDown open into the first row, ArrowUp into the last,
117
+ // and focus returns here on close (`floating/menu-keyboard.ts`). Inert on
118
+ // native, where there is no DOM node to listen on.
119
+ useMenuTriggerKeys(menu.anchorRef, {
120
+ open: menu.open,
121
+ setOpen: menu.setOpen,
122
+ disabled,
123
+ intent: menu.focusIntent,
124
+ });
125
+
126
+ // `flex items-center rounded-md px-2 py-1.5`, plus `bg-accent` while its menu
127
+ // is open, and `text-sm font-medium` for the label. A menubar trigger is a
128
+ // BUTTON with chrome of its own, not a bare hit box — leaving it unstyled is
129
+ // why a Bloom menubar read as loose text against a pill-per-menu bar. The
130
+ // same chrome on both platforms, so the bar reads identically. `asChild`
131
+ // still hands the whole thing to the caller.
132
+ const trigger = (
133
+ <StyledView
134
+ className={cx(
135
+ MENUBAR_TRIGGER_CLASS,
136
+ menu.open && MENUBAR_TRIGGER_OPEN_CLASS,
137
+ className,
138
+ )}
139
+ style={{ backgroundColor: menu.open ? palette.rowHighlight : 'transparent' }}>
140
+ {typeof children === 'string' ? (
141
+ <StyledText
142
+ className={MENUBAR_TRIGGER_TEXT_CLASS}
143
+ // `text-body-medium text-text-primary`, in Inter.
144
+ style={[menuType('body-medium'), { color: palette.text }]}>
145
+ {children}
146
+ </StyledText>
147
+ ) : (
148
+ children
149
+ )}
150
+ </StyledView>
151
+ );
152
+
153
+ return (
154
+ <TriggerSlot
155
+ asChild={asChild}
156
+ anchorRef={menu.anchorRef}
157
+ style={style}
158
+ testID={testID}
159
+ handle={{
160
+ onPress: () => menu.setOpen(!menu.open),
161
+ disabled,
162
+ accessibilityLabel: label,
163
+ accessibilityRole: 'button',
164
+ 'aria-haspopup': MENU_TRIGGER_POPUP,
165
+ 'aria-expanded': menu.open,
166
+ }}>
167
+ {asChild ? children : trigger}
168
+ </TriggerSlot>
169
+ );
170
+ }
@@ -1,3 +1,8 @@
1
+ // AUTO-GENERATED by scripts/generate-platform-exports.mjs — DO NOT EDIT.
2
+ // Source of truth: src/menubar/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
  Menubar,
3
8
  MenubarMenu,
@@ -1,8 +1,8 @@
1
- /**
2
- * Web variant of the `motion` barrel. Only the three layout-animation presets
3
- * fork — see `motion.web.ts` for why. `ScreenTransition` is universal: it already
4
- * branches on `Platform.OS` internally.
5
- */
1
+ // AUTO-GENERATED by scripts/generate-platform-exports.mjs — DO NOT EDIT.
2
+ // Source of truth: src/motion/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
+
6
6
  export { ScaleAndFadeIn, ScaleAndFadeOut, ShrinkAndPop } from './motion.web';
7
7
  export { ScreenTransition } from './ScreenTransition';
8
8
  export type { ScreenTransitionProps, ScreenTransitionDirection } from './types';
@@ -1,3 +1,8 @@
1
+ // AUTO-GENERATED by scripts/generate-platform-exports.mjs — DO NOT EDIT.
2
+ // Source of truth: src/popover/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 { Popover, PopoverTrigger, PopoverContent } from './Popover.web';
2
7
  export {
3
8
  PopoverHeader,
@@ -6,25 +6,41 @@
6
6
  * header/footer `px-2` is measured against — 18px from the panel edge on every
7
7
  * side ("panel p-2.5 + row px-2").
8
8
  *
9
- * PopoverHeader flex items-center gap-2 px-2 pt-1 (dashboard team menu)
9
+ * PopoverHeader flex items-center gap-2 px-2 pt-1 (sidebar team menu)
10
10
  * PopoverTitle text-body-medium text-text-primary (secondary: group label)
11
11
  * PopoverDescription text-body-regular text-text-secondary
12
- * PopoverFooter flex items-center gap-3 px-2 pb-2 (user menu actions)
12
+ * PopoverFooter flex items-center gap-3 px-2 pb-2 (sidebar user menu actions)
13
13
  * PopoverSeparator -mx-2.5 my-2.5 h-px bg-border-button-default
14
14
  *
15
15
  * Popovers have no close button and no arrow, so neither is a part.
16
16
  *
17
- * Colours are resolved inline from `menu-palette.ts`; a text colour default is
18
- * applied only when the caller passes no `className`, so a `text-*` utility is
19
- * never outranked (AGENTS.md, "Style and `className`").
17
+ * ── HOW A CALLER'S CLASS STILL WINS ─────────────────────────────────────────
18
+ *
19
+ * Every default here is INLINE, because the colours are ramp stops that exist
20
+ * as no CSS variable and the geometry has to agree with them. But an inline
21
+ * style beats ANY class on web, so a naive inline default silently outranks
22
+ * whatever the caller passes: `<PopoverSeparator className="bg-red-500" />`
23
+ * painted the palette colour, and `<PopoverHeader className="px-4" />` kept
24
+ * its 8px.
25
+ *
26
+ * So each part omits exactly the properties the caller's utilities NAME, using
27
+ * the same token scan the panel uses (`classChromeOverrides` in `surface.ts`).
28
+ * The parts previously used an all-or-nothing guard instead — drop the colour
29
+ * default if ANY `className` is present — which failed in the other direction:
30
+ * `<PopoverTitle className="mt-1">` lost its colour entirely.
31
+ *
32
+ * The trade-off is real and the panel already made it: on a web build whose
33
+ * Tailwind/NativeWind pipeline is not wired (`AGENTS.md`, "Consumer web CSS
34
+ * pipeline"), a named property falls back to NOTHING rather than to the
35
+ * default. A caller who names it is asking to own it.
20
36
  */
21
37
  import React from 'react';
22
- import { StyleSheet, View } from 'react-native';
38
+ import { StyleSheet, View, type ViewStyle } from 'react-native';
23
39
 
24
40
  import { useMenuPalette } from '../floating/menu-palette';
25
41
  import { StyledView } from '../styles/styled-primitives';
26
42
  import { Text } from '../typography';
27
- import { POPOVER_PADDING } from './surface';
43
+ import { classChromeOverrides, POPOVER_PADDING, type PopoverChromeKey } from './surface';
28
44
  import type {
29
45
  PopoverDescriptionProps,
30
46
  PopoverFooterProps,
@@ -33,9 +49,47 @@ import type {
33
49
  PopoverTitleProps,
34
50
  } from './types';
35
51
 
52
+ /**
53
+ * `base` minus the properties the caller's `className` claims.
54
+ *
55
+ * It walks BASE, not the map: a property with no chrome key is one no utility
56
+ * can name, so it is always kept. Walking the map instead would silently drop
57
+ * whatever was added to a part's stylesheet without being classified — the
58
+ * failure would be a missing default, with nothing to report it.
59
+ */
60
+ function kept(base: ViewStyle, owned: ReadonlySet<PopoverChromeKey>): ViewStyle {
61
+ if (owned.size === 0) return base;
62
+ const out: ViewStyle = {};
63
+ for (const [property, value] of Object.entries(base)) {
64
+ const key = PROPERTY_KEY[property];
65
+ if (key === undefined || !owned.has(key)) {
66
+ Object.assign(out, { [property]: value });
67
+ }
68
+ }
69
+ return out;
70
+ }
71
+
72
+ /** Which chrome key each style property belongs to. */
73
+ const PROPERTY_KEY: Record<string, PopoverChromeKey | undefined> = {
74
+ flexDirection: 'flexDirection',
75
+ alignItems: 'alignItems',
76
+ gap: 'gap',
77
+ paddingLeft: 'paddingLeft',
78
+ paddingRight: 'paddingRight',
79
+ paddingTop: 'paddingTop',
80
+ paddingBottom: 'paddingBottom',
81
+ marginLeft: 'marginLeft',
82
+ marginRight: 'marginRight',
83
+ marginTop: 'marginTop',
84
+ marginBottom: 'marginBottom',
85
+ height: 'height',
86
+ backgroundColor: 'background',
87
+ };
88
+
36
89
  export function PopoverHeader({ leading, children, className, style, testID }: PopoverHeaderProps) {
90
+ const owned = classChromeOverrides(className);
37
91
  return (
38
- <StyledView className={className} style={[styles.header, style]} testID={testID}>
92
+ <StyledView className={className} style={[kept(styles.header, owned), style]} testID={testID}>
39
93
  {leading ? <View style={styles.leading}>{leading}</View> : null}
40
94
  <View style={styles.headerText}>{children}</View>
41
95
  </StyledView>
@@ -57,7 +111,7 @@ export function PopoverTitle({
57
111
  variant="body-medium"
58
112
  numberOfLines={numberOfLines}
59
113
  className={className}
60
- style={[className ? null : { color }, style]}
114
+ style={[classChromeOverrides(className).has('color') ? null : { color }, style]}
61
115
  testID={testID}>
62
116
  {children}
63
117
  </Text>
@@ -77,7 +131,12 @@ export function PopoverDescription({
77
131
  variant="body-regular"
78
132
  numberOfLines={numberOfLines}
79
133
  className={className}
80
- style={[className ? null : { color: palette.textSecondary }, style]}
134
+ style={[
135
+ classChromeOverrides(className).has('color')
136
+ ? null
137
+ : { color: palette.textSecondary },
138
+ style,
139
+ ]}
81
140
  testID={testID}>
82
141
  {children}
83
142
  </Text>
@@ -85,8 +144,9 @@ export function PopoverDescription({
85
144
  }
86
145
 
87
146
  export function PopoverFooter({ children, className, style, testID }: PopoverFooterProps) {
147
+ const owned = classChromeOverrides(className);
88
148
  return (
89
- <StyledView className={className} style={[styles.footer, style]} testID={testID}>
149
+ <StyledView className={className} style={[kept(styles.footer, owned), style]} testID={testID}>
90
150
  {children}
91
151
  </StyledView>
92
152
  );
@@ -94,12 +154,16 @@ export function PopoverFooter({ children, className, style, testID }: PopoverFoo
94
154
 
95
155
  export function PopoverSeparator({ className, style, testID }: PopoverSeparatorProps) {
96
156
  const palette = useMenuPalette();
157
+ const owned = classChromeOverrides(className);
97
158
  return (
98
159
  <StyledView
99
160
  // Decorative: the sections it divides are announced on their own.
100
161
  aria-hidden
101
162
  className={className}
102
- style={[styles.separator, { backgroundColor: palette.border }, style]}
163
+ style={[
164
+ kept({ ...styles.separator, backgroundColor: palette.border }, owned),
165
+ style,
166
+ ]}
103
167
  testID={testID}
104
168
  />
105
169
  );
@@ -1,9 +1,8 @@
1
1
  /**
2
2
  * The popover PANEL — Bloom's one floating surface, resolved to inline style.
3
3
  *
4
- * Every floating panel (`dropdown/menu-styles.ts`'s `MENU_POPOVER_SURFACE`, the
5
- * dashboard team/user menus, the calendar inbox menu, the ai-chat menus) spells
6
- * the same class string:
4
+ * Every floating panel in the fleet — the sidebar team and user menus, the
5
+ * calendar inbox menu, the ai-chat menus — spells the same class string:
7
6
  *
8
7
  * w-[266px] max-w-[calc(100vw-32px)] overflow-y-auto
9
8
  * rounded-2xl border border-border-button-default
@@ -32,7 +31,7 @@
32
31
  import type { MenuPalette } from '../floating/menu-palette';
33
32
  import type { WebCssStyle } from '../styles/web-view-style';
34
33
 
35
- /** `w-[266px]` — `MENU_POPOVER_WIDTH`. */
34
+ /** `w-[266px]` — the one panel width every floating surface shares. */
36
35
  export const POPOVER_WIDTH = 266;
37
36
  /** `rounded-2xl`. */
38
37
  export const POPOVER_RADIUS = 16;
@@ -46,36 +45,91 @@ export const POPOVER_SIDE_OFFSET = 8;
46
45
  export type PopoverChromeKey =
47
46
  | 'width'
48
47
  | 'maxWidth'
49
- | 'padding'
48
+ | 'paddingTop'
49
+ | 'paddingBottom'
50
+ | 'paddingLeft'
51
+ | 'paddingRight'
50
52
  | 'radius'
51
53
  | 'borderWidth'
52
54
  | 'borderColor'
53
55
  | 'background'
54
56
  | 'shadow'
55
- | 'overflow';
57
+ | 'overflow'
58
+ // The rest are the PANEL PARTS' chrome (`parts.tsx`). The panel itself sets
59
+ // no default for any of them, so `resolvePopoverSurfaceStyle` ignores them.
60
+ | 'color'
61
+ | 'gap'
62
+ | 'marginTop'
63
+ | 'marginBottom'
64
+ | 'marginLeft'
65
+ | 'marginRight'
66
+ | 'height'
67
+ | 'flexDirection'
68
+ | 'alignItems';
56
69
 
57
70
  const BORDER_WIDTH = /^border(-[xytrblse])?(-\d+(\.\d+)?|-\[[^\]]+px\])?$/;
58
71
 
72
+ /**
73
+ * The sides a spacing utility's axis letter claims. `p-4` has no letter and
74
+ * claims all four; `px`/`py` are the pairs; `pt`/`pb`/`pl`/`pr` are single
75
+ * sides. `ps`/`pe` are the LOGICAL start and end — one side each, not the
76
+ * pair — which react-native-web resolves to left and right in an LTR
77
+ * document. Treating them as the pair would drop a default the caller never
78
+ * asked to own.
79
+ */
80
+ function sidesOf(letter: string | undefined, property: 'padding' | 'margin'): PopoverChromeKey[] {
81
+ const sides =
82
+ letter === undefined ? ['Top', 'Bottom', 'Left', 'Right']
83
+ : letter === 'x' ? ['Left', 'Right']
84
+ : letter === 'y' ? ['Top', 'Bottom']
85
+ : letter === 't' ? ['Top']
86
+ : letter === 'b' ? ['Bottom']
87
+ : letter === 'l' || letter === 's' ? ['Left']
88
+ : letter === 'r' || letter === 'e' ? ['Right']
89
+ : [];
90
+ return sides.map((side) => `${property}${side}` as PopoverChromeKey);
91
+ }
92
+
59
93
  /**
60
94
  * Which chrome properties a caller's utility classes set. Variants (`dark:`,
61
95
  * `md:`, `hover:`), the important `!` and a negative `-` are stripped first, so
62
96
  * `md:!p-0` counts as padding.
97
+ *
98
+ * Padding and margin are claimed PER SIDE, because the utilities are: `px-4`
99
+ * names left and right and says nothing about the top, so a part that also
100
+ * sets `paddingTop` must keep it. Treating them as one key dropped a header's
101
+ * `pt-1` for a caller who only asked for wider sides.
102
+ *
103
+ * `text-*` is counted as a COLOUR, including the size steps (`text-sm`). That
104
+ * is deliberately imprecise: telling `text-sm` from `text-red-500` means
105
+ * knowing the consumer's palette, and the alternative the parts used before
106
+ * this — drop the colour default whenever ANY `className` is passed — is
107
+ * strictly worse, since it loses the colour to an unrelated `mt-1`.
63
108
  */
64
109
  export function classChromeOverrides(className?: string): ReadonlySet<PopoverChromeKey> {
65
110
  const keys = new Set<PopoverChromeKey>();
66
111
  if (!className) return keys;
112
+ let spacing: RegExpExecArray | null;
67
113
  for (const raw of className.split(/\s+/)) {
68
114
  if (!raw) continue;
69
115
  const token = raw.slice(raw.lastIndexOf(':') + 1).replace(/^!/, '').replace(/^-/, '');
70
116
  if (/^(w|size)-/.test(token)) keys.add('width');
71
117
  else if (/^max-w-/.test(token)) keys.add('maxWidth');
72
- else if (/^p[xytrblse]?-/.test(token)) keys.add('padding');
118
+ else if ((spacing = /^([pm])([xytrbles])?-/.exec(token))) {
119
+ const property = spacing[1] === 'p' ? 'padding' : 'margin';
120
+ for (const key of sidesOf(spacing[2], property)) keys.add(key);
121
+ }
73
122
  else if (/^rounded(-|$)/.test(token)) keys.add('radius');
74
123
  else if (BORDER_WIDTH.test(token)) keys.add('borderWidth');
75
124
  else if (/^border-/.test(token)) keys.add('borderColor');
76
125
  else if (/^bg-/.test(token)) keys.add('background');
77
126
  else if (/^shadow(-|$)/.test(token)) keys.add('shadow');
78
127
  else if (/^overflow-/.test(token)) keys.add('overflow');
128
+ else if (/^text-/.test(token)) keys.add('color');
129
+ else if (/^gap(-|$)/.test(token)) keys.add('gap');
130
+ else if (/^h-/.test(token)) keys.add('height');
131
+ else if (/^flex-(row|col)/.test(token)) keys.add('flexDirection');
132
+ else if (/^items-/.test(token)) keys.add('alignItems');
79
133
  }
80
134
  return keys;
81
135
  }
@@ -96,14 +150,13 @@ export function resolvePopoverSurfaceStyle(
96
150
  if (!overridden.has('maxWidth') && viewportWidth !== undefined) {
97
151
  style.maxWidth = Math.max(0, viewportWidth - POPOVER_VIEWPORT_INSET);
98
152
  }
99
- if (!overridden.has('padding')) {
100
- // Longhands: a caller's `style` override of one side must not lose to a
101
- // shorthand react-native-web ranks above it (AGENTS.md, "Style").
102
- style.paddingTop = POPOVER_PADDING;
103
- style.paddingBottom = POPOVER_PADDING;
104
- style.paddingLeft = POPOVER_PADDING;
105
- style.paddingRight = POPOVER_PADDING;
106
- }
153
+ // Longhands, one side at a time: a caller's `style` override of one side must
154
+ // not lose to a shorthand react-native-web ranks above it (AGENTS.md,
155
+ // "Style"), and a caller who writes `px-4` is claiming the sides, not the top.
156
+ if (!overridden.has('paddingTop')) style.paddingTop = POPOVER_PADDING;
157
+ if (!overridden.has('paddingBottom')) style.paddingBottom = POPOVER_PADDING;
158
+ if (!overridden.has('paddingLeft')) style.paddingLeft = POPOVER_PADDING;
159
+ if (!overridden.has('paddingRight')) style.paddingRight = POPOVER_PADDING;
107
160
  if (!overridden.has('radius')) style.borderRadius = POPOVER_RADIUS;
108
161
  if (!overridden.has('borderWidth')) style.borderWidth = 1;
109
162
  if (!overridden.has('borderColor')) style.borderColor = palette.border;