@oxyhq/bloom 0.50.2 → 0.51.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 (536) hide show
  1. package/NOTICE +89 -0
  2. package/README.md +12 -7
  3. package/lib/commonjs/avatar-group/AvatarGroup.web.js +2 -1
  4. package/lib/commonjs/avatar-group/AvatarGroup.web.js.map +1 -1
  5. package/lib/commonjs/bottom-sheet/index.web.js +2 -1
  6. package/lib/commonjs/bottom-sheet/index.web.js.map +1 -1
  7. package/lib/commonjs/context-menu/index.web.js +3 -2
  8. package/lib/commonjs/context-menu/index.web.js.map +1 -1
  9. package/lib/commonjs/dialog/Dialog.web.js +4 -3
  10. package/lib/commonjs/dialog/Dialog.web.js.map +1 -1
  11. package/lib/commonjs/index.js +90 -83
  12. package/lib/commonjs/index.js.map +1 -1
  13. package/lib/commonjs/index.web.js +116 -109
  14. package/lib/commonjs/index.web.js.map +1 -1
  15. package/lib/commonjs/menu/index.web.js +2 -1
  16. package/lib/commonjs/menu/index.web.js.map +1 -1
  17. package/lib/commonjs/popover/index.web.js +3 -2
  18. package/lib/commonjs/popover/index.web.js.map +1 -1
  19. package/lib/commonjs/portal/index.js +4 -1
  20. package/lib/commonjs/portal/index.js.map +1 -1
  21. package/lib/commonjs/progressive-blur/index.js +79 -0
  22. package/lib/commonjs/progressive-blur/index.js.map +1 -0
  23. package/lib/commonjs/progressive-blur/index.web.js +67 -0
  24. package/lib/commonjs/progressive-blur/index.web.js.map +1 -0
  25. package/lib/commonjs/progressive-blur/shared.js +66 -0
  26. package/lib/commonjs/progressive-blur/shared.js.map +1 -0
  27. package/lib/commonjs/progressive-blur/types.js +6 -0
  28. package/lib/commonjs/progressive-blur/types.js.map +1 -0
  29. package/lib/commonjs/select/index.web.js +2 -1
  30. package/lib/commonjs/select/index.web.js.map +1 -1
  31. package/lib/commonjs/styles/web-view-style.js +26 -0
  32. package/lib/commonjs/styles/web-view-style.js.map +1 -0
  33. package/lib/commonjs/tab-bar/TabBarBase.js +415 -0
  34. package/lib/commonjs/tab-bar/TabBarBase.js.map +1 -0
  35. package/lib/commonjs/tab-bar/expo-router/RouterTabBar.js +83 -0
  36. package/lib/commonjs/tab-bar/expo-router/RouterTabBar.js.map +1 -0
  37. package/lib/commonjs/tab-bar/expo-router/fading-tab-screen.js +119 -0
  38. package/lib/commonjs/tab-bar/expo-router/fading-tab-screen.js.map +1 -0
  39. package/lib/commonjs/tab-bar/expo-router/index.js +26 -0
  40. package/lib/commonjs/tab-bar/expo-router/index.js.map +1 -0
  41. package/lib/commonjs/tab-bar/glyph.js +43 -0
  42. package/lib/commonjs/tab-bar/glyph.js.map +1 -0
  43. package/lib/commonjs/tab-bar/glyph.native.js +55 -0
  44. package/lib/commonjs/tab-bar/glyph.native.js.map +1 -0
  45. package/lib/commonjs/tab-bar/index.js +65 -0
  46. package/lib/commonjs/tab-bar/index.js.map +1 -0
  47. package/lib/commonjs/tab-bar/index.web.js +67 -0
  48. package/lib/commonjs/tab-bar/index.web.js.map +1 -0
  49. package/lib/commonjs/tab-bar/minimize-context.js +127 -0
  50. package/lib/commonjs/tab-bar/minimize-context.js.map +1 -0
  51. package/lib/commonjs/tab-bar/shared.js +139 -0
  52. package/lib/commonjs/tab-bar/shared.js.map +1 -0
  53. package/lib/commonjs/tab-bar/surface.js +50 -0
  54. package/lib/commonjs/tab-bar/surface.js.map +1 -0
  55. package/lib/commonjs/tab-bar/surface.native.js +56 -0
  56. package/lib/commonjs/tab-bar/surface.native.js.map +1 -0
  57. package/lib/commonjs/tab-bar/surface.web.js +59 -0
  58. package/lib/commonjs/tab-bar/surface.web.js.map +1 -0
  59. package/lib/commonjs/tab-bar/types.js +6 -0
  60. package/lib/commonjs/tab-bar/types.js.map +1 -0
  61. package/lib/commonjs/toast/Positioner.js +117 -0
  62. package/lib/commonjs/toast/Positioner.js.map +1 -0
  63. package/lib/commonjs/toast/ToastContent.js +301 -0
  64. package/lib/commonjs/toast/ToastContent.js.map +1 -0
  65. package/lib/commonjs/toast/ToastHost.js +69 -0
  66. package/lib/commonjs/toast/ToastHost.js.map +1 -0
  67. package/lib/commonjs/toast/ToastHost.native.js +44 -0
  68. package/lib/commonjs/toast/ToastHost.native.js.map +1 -0
  69. package/lib/commonjs/toast/ToastIcon.js +57 -0
  70. package/lib/commonjs/toast/ToastIcon.js.map +1 -0
  71. package/lib/commonjs/toast/ToastRow.js +411 -0
  72. package/lib/commonjs/toast/ToastRow.js.map +1 -0
  73. package/lib/commonjs/toast/ToastSwipeHandler.js +189 -0
  74. package/lib/commonjs/toast/ToastSwipeHandler.js.map +1 -0
  75. package/lib/commonjs/toast/Toaster.js +205 -0
  76. package/lib/commonjs/toast/Toaster.js.map +1 -0
  77. package/lib/commonjs/toast/animations.js +274 -0
  78. package/lib/commonjs/toast/animations.js.map +1 -0
  79. package/lib/commonjs/toast/constants.js +56 -0
  80. package/lib/commonjs/toast/constants.js.map +1 -0
  81. package/lib/commonjs/toast/context.js +42 -0
  82. package/lib/commonjs/toast/context.js.map +1 -0
  83. package/lib/commonjs/toast/index.js +32 -126
  84. package/lib/commonjs/toast/index.js.map +1 -1
  85. package/lib/commonjs/toast/position-utils.js +115 -0
  86. package/lib/commonjs/toast/position-utils.js.map +1 -0
  87. package/lib/commonjs/toast/positioner-utils.js +141 -0
  88. package/lib/commonjs/toast/positioner-utils.js.map +1 -0
  89. package/lib/commonjs/toast/toast-comparator.js +28 -0
  90. package/lib/commonjs/toast/toast-comparator.js.map +1 -0
  91. package/lib/commonjs/toast/toast-fns.js +90 -0
  92. package/lib/commonjs/toast/toast-fns.js.map +1 -0
  93. package/lib/commonjs/toast/toast-store.js +352 -0
  94. package/lib/commonjs/toast/toast-store.js.map +1 -0
  95. package/lib/commonjs/toast/toast-timers.js +110 -0
  96. package/lib/commonjs/toast/toast-timers.js.map +1 -0
  97. package/lib/commonjs/toast/types.js +42 -0
  98. package/lib/commonjs/toast/types.js.map +1 -1
  99. package/lib/commonjs/toast/use-animated-target.js +57 -0
  100. package/lib/commonjs/toast/use-animated-target.js.map +1 -0
  101. package/lib/commonjs/toast/use-app-state.js +76 -0
  102. package/lib/commonjs/toast/use-app-state.js.map +1 -0
  103. package/lib/commonjs/toast/use-toast-colors.js +114 -0
  104. package/lib/commonjs/toast/use-toast-colors.js.map +1 -0
  105. package/lib/commonjs/toast/use-toast-position.js +40 -0
  106. package/lib/commonjs/toast/use-toast-position.js.map +1 -0
  107. package/lib/commonjs/tooltip/index.web.js +2 -1
  108. package/lib/commonjs/tooltip/index.web.js.map +1 -1
  109. package/lib/commonjs/zoomable-image-gallery/ZoomableImageGallery.js +20 -8
  110. package/lib/commonjs/zoomable-image-gallery/ZoomableImageGallery.js.map +1 -1
  111. package/lib/module/avatar-group/AvatarGroup.web.js +2 -1
  112. package/lib/module/avatar-group/AvatarGroup.web.js.map +1 -1
  113. package/lib/module/bottom-sheet/index.web.js +2 -1
  114. package/lib/module/bottom-sheet/index.web.js.map +1 -1
  115. package/lib/module/context-menu/index.web.js +3 -2
  116. package/lib/module/context-menu/index.web.js.map +1 -1
  117. package/lib/module/dialog/Dialog.web.js +4 -3
  118. package/lib/module/dialog/Dialog.web.js.map +1 -1
  119. package/lib/module/index.js +3 -2
  120. package/lib/module/index.js.map +1 -1
  121. package/lib/module/index.web.js +3 -2
  122. package/lib/module/index.web.js.map +1 -1
  123. package/lib/module/menu/index.web.js +2 -1
  124. package/lib/module/menu/index.web.js.map +1 -1
  125. package/lib/module/popover/index.web.js +3 -2
  126. package/lib/module/popover/index.web.js.map +1 -1
  127. package/lib/module/portal/index.js +4 -1
  128. package/lib/module/portal/index.js.map +1 -1
  129. package/lib/module/progressive-blur/index.js +74 -0
  130. package/lib/module/progressive-blur/index.js.map +1 -0
  131. package/lib/module/progressive-blur/index.web.js +62 -0
  132. package/lib/module/progressive-blur/index.web.js.map +1 -0
  133. package/lib/module/progressive-blur/shared.js +60 -0
  134. package/lib/module/progressive-blur/shared.js.map +1 -0
  135. package/lib/module/progressive-blur/types.js +4 -0
  136. package/lib/module/progressive-blur/types.js.map +1 -0
  137. package/lib/module/select/index.web.js +2 -1
  138. package/lib/module/select/index.web.js.map +1 -1
  139. package/lib/module/styles/web-view-style.js +22 -0
  140. package/lib/module/styles/web-view-style.js.map +1 -0
  141. package/lib/module/tab-bar/TabBarBase.js +408 -0
  142. package/lib/module/tab-bar/TabBarBase.js.map +1 -0
  143. package/lib/module/tab-bar/expo-router/RouterTabBar.js +78 -0
  144. package/lib/module/tab-bar/expo-router/RouterTabBar.js.map +1 -0
  145. package/lib/module/tab-bar/expo-router/fading-tab-screen.js +113 -0
  146. package/lib/module/tab-bar/expo-router/fading-tab-screen.js.map +1 -0
  147. package/lib/module/tab-bar/expo-router/index.js +15 -0
  148. package/lib/module/tab-bar/expo-router/index.js.map +1 -0
  149. package/lib/module/tab-bar/glyph.js +38 -0
  150. package/lib/module/tab-bar/glyph.js.map +1 -0
  151. package/lib/module/tab-bar/glyph.native.js +50 -0
  152. package/lib/module/tab-bar/glyph.native.js.map +1 -0
  153. package/lib/module/tab-bar/index.js +24 -0
  154. package/lib/module/tab-bar/index.js.map +1 -0
  155. package/lib/module/tab-bar/index.web.js +26 -0
  156. package/lib/module/tab-bar/index.web.js.map +1 -0
  157. package/lib/module/tab-bar/minimize-context.js +118 -0
  158. package/lib/module/tab-bar/minimize-context.js.map +1 -0
  159. package/lib/module/tab-bar/shared.js +132 -0
  160. package/lib/module/tab-bar/shared.js.map +1 -0
  161. package/lib/module/tab-bar/surface.js +44 -0
  162. package/lib/module/tab-bar/surface.js.map +1 -0
  163. package/lib/module/tab-bar/surface.native.js +50 -0
  164. package/lib/module/tab-bar/surface.native.js.map +1 -0
  165. package/lib/module/tab-bar/surface.web.js +53 -0
  166. package/lib/module/tab-bar/surface.web.js.map +1 -0
  167. package/lib/module/tab-bar/types.js +4 -0
  168. package/lib/module/tab-bar/types.js.map +1 -0
  169. package/lib/module/toast/Positioner.js +110 -0
  170. package/lib/module/toast/Positioner.js.map +1 -0
  171. package/lib/module/toast/ToastContent.js +295 -0
  172. package/lib/module/toast/ToastContent.js.map +1 -0
  173. package/lib/module/toast/ToastHost.js +63 -0
  174. package/lib/module/toast/ToastHost.js.map +1 -0
  175. package/lib/module/toast/ToastHost.native.js +38 -0
  176. package/lib/module/toast/ToastHost.native.js.map +1 -0
  177. package/lib/module/toast/ToastIcon.js +52 -0
  178. package/lib/module/toast/ToastIcon.js.map +1 -0
  179. package/lib/module/toast/ToastRow.js +407 -0
  180. package/lib/module/toast/ToastRow.js.map +1 -0
  181. package/lib/module/toast/ToastSwipeHandler.js +182 -0
  182. package/lib/module/toast/ToastSwipeHandler.js.map +1 -0
  183. package/lib/module/toast/Toaster.js +198 -0
  184. package/lib/module/toast/Toaster.js.map +1 -0
  185. package/lib/module/toast/animations.js +261 -0
  186. package/lib/module/toast/animations.js.map +1 -0
  187. package/lib/module/toast/constants.js +52 -0
  188. package/lib/module/toast/constants.js.map +1 -0
  189. package/lib/module/toast/context.js +34 -0
  190. package/lib/module/toast/context.js.map +1 -0
  191. package/lib/module/toast/index.js +27 -103
  192. package/lib/module/toast/index.js.map +1 -1
  193. package/lib/module/toast/position-utils.js +107 -0
  194. package/lib/module/toast/position-utils.js.map +1 -0
  195. package/lib/module/toast/positioner-utils.js +134 -0
  196. package/lib/module/toast/positioner-utils.js.map +1 -0
  197. package/lib/module/toast/toast-comparator.js +22 -0
  198. package/lib/module/toast/toast-comparator.js.map +1 -0
  199. package/lib/module/toast/toast-fns.js +85 -0
  200. package/lib/module/toast/toast-fns.js.map +1 -0
  201. package/lib/module/toast/toast-store.js +346 -0
  202. package/lib/module/toast/toast-store.js.map +1 -0
  203. package/lib/module/toast/toast-timers.js +104 -0
  204. package/lib/module/toast/toast-timers.js.map +1 -0
  205. package/lib/module/toast/types.js +38 -0
  206. package/lib/module/toast/types.js.map +1 -1
  207. package/lib/module/toast/use-animated-target.js +52 -0
  208. package/lib/module/toast/use-animated-target.js.map +1 -0
  209. package/lib/module/toast/use-app-state.js +70 -0
  210. package/lib/module/toast/use-app-state.js.map +1 -0
  211. package/lib/module/toast/use-toast-colors.js +109 -0
  212. package/lib/module/toast/use-toast-colors.js.map +1 -0
  213. package/lib/module/toast/use-toast-position.js +35 -0
  214. package/lib/module/toast/use-toast-position.js.map +1 -0
  215. package/lib/module/tooltip/index.web.js +2 -1
  216. package/lib/module/tooltip/index.web.js.map +1 -1
  217. package/lib/module/zoomable-image-gallery/ZoomableImageGallery.js +20 -8
  218. package/lib/module/zoomable-image-gallery/ZoomableImageGallery.js.map +1 -1
  219. package/lib/typescript/commonjs/avatar-group/AvatarGroup.web.d.ts.map +1 -1
  220. package/lib/typescript/commonjs/bottom-sheet/index.web.d.ts.map +1 -1
  221. package/lib/typescript/commonjs/context-menu/index.web.d.ts.map +1 -1
  222. package/lib/typescript/commonjs/dialog/Dialog.web.d.ts.map +1 -1
  223. package/lib/typescript/commonjs/index.d.ts +2 -1
  224. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  225. package/lib/typescript/commonjs/index.web.d.ts +2 -1
  226. package/lib/typescript/commonjs/index.web.d.ts.map +1 -1
  227. package/lib/typescript/commonjs/menu/index.web.d.ts.map +1 -1
  228. package/lib/typescript/commonjs/popover/index.web.d.ts.map +1 -1
  229. package/lib/typescript/commonjs/portal/index.d.ts.map +1 -1
  230. package/lib/typescript/commonjs/progressive-blur/index.d.ts +23 -0
  231. package/lib/typescript/commonjs/progressive-blur/index.d.ts.map +1 -0
  232. package/lib/typescript/commonjs/progressive-blur/index.web.d.ts +30 -0
  233. package/lib/typescript/commonjs/progressive-blur/index.web.d.ts.map +1 -0
  234. package/lib/typescript/commonjs/progressive-blur/shared.d.ts +35 -0
  235. package/lib/typescript/commonjs/progressive-blur/shared.d.ts.map +1 -0
  236. package/lib/typescript/commonjs/progressive-blur/types.d.ts +21 -0
  237. package/lib/typescript/commonjs/progressive-blur/types.d.ts.map +1 -0
  238. package/lib/typescript/commonjs/select/index.web.d.ts.map +1 -1
  239. package/lib/typescript/commonjs/styles/web-view-style.d.ts +21 -0
  240. package/lib/typescript/commonjs/styles/web-view-style.d.ts.map +1 -0
  241. package/lib/typescript/commonjs/tab-bar/TabBarBase.d.ts +36 -0
  242. package/lib/typescript/commonjs/tab-bar/TabBarBase.d.ts.map +1 -0
  243. package/lib/typescript/commonjs/tab-bar/expo-router/RouterTabBar.d.ts +59 -0
  244. package/lib/typescript/commonjs/tab-bar/expo-router/RouterTabBar.d.ts.map +1 -0
  245. package/lib/typescript/commonjs/tab-bar/expo-router/fading-tab-screen.d.ts +11 -0
  246. package/lib/typescript/commonjs/tab-bar/expo-router/fading-tab-screen.d.ts.map +1 -0
  247. package/lib/typescript/commonjs/tab-bar/expo-router/index.d.ts +14 -0
  248. package/lib/typescript/commonjs/tab-bar/expo-router/index.d.ts.map +1 -0
  249. package/lib/typescript/commonjs/tab-bar/glyph.d.ts +6 -0
  250. package/lib/typescript/commonjs/tab-bar/glyph.d.ts.map +1 -0
  251. package/lib/typescript/commonjs/tab-bar/glyph.native.d.ts +6 -0
  252. package/lib/typescript/commonjs/tab-bar/glyph.native.d.ts.map +1 -0
  253. package/lib/typescript/commonjs/tab-bar/index.d.ts +12 -0
  254. package/lib/typescript/commonjs/tab-bar/index.d.ts.map +1 -0
  255. package/lib/typescript/commonjs/tab-bar/index.web.d.ts +12 -0
  256. package/lib/typescript/commonjs/tab-bar/index.web.d.ts.map +1 -0
  257. package/lib/typescript/commonjs/tab-bar/minimize-context.d.ts +51 -0
  258. package/lib/typescript/commonjs/tab-bar/minimize-context.d.ts.map +1 -0
  259. package/lib/typescript/commonjs/tab-bar/shared.d.ts +93 -0
  260. package/lib/typescript/commonjs/tab-bar/shared.d.ts.map +1 -0
  261. package/lib/typescript/commonjs/tab-bar/surface.d.ts +6 -0
  262. package/lib/typescript/commonjs/tab-bar/surface.d.ts.map +1 -0
  263. package/lib/typescript/commonjs/tab-bar/surface.native.d.ts +6 -0
  264. package/lib/typescript/commonjs/tab-bar/surface.native.d.ts.map +1 -0
  265. package/lib/typescript/commonjs/tab-bar/surface.web.d.ts +6 -0
  266. package/lib/typescript/commonjs/tab-bar/surface.web.d.ts.map +1 -0
  267. package/lib/typescript/commonjs/tab-bar/types.d.ts +85 -0
  268. package/lib/typescript/commonjs/tab-bar/types.d.ts.map +1 -0
  269. package/lib/typescript/commonjs/toast/Positioner.d.ts +21 -0
  270. package/lib/typescript/commonjs/toast/Positioner.d.ts.map +1 -0
  271. package/lib/typescript/commonjs/toast/ToastContent.d.ts +14 -0
  272. package/lib/typescript/commonjs/toast/ToastContent.d.ts.map +1 -0
  273. package/lib/typescript/commonjs/toast/ToastHost.d.ts +6 -0
  274. package/lib/typescript/commonjs/toast/ToastHost.d.ts.map +1 -0
  275. package/lib/typescript/commonjs/toast/ToastHost.native.d.ts +6 -0
  276. package/lib/typescript/commonjs/toast/ToastHost.native.d.ts.map +1 -0
  277. package/lib/typescript/commonjs/toast/ToastIcon.d.ts +9 -0
  278. package/lib/typescript/commonjs/toast/ToastIcon.d.ts.map +1 -0
  279. package/lib/typescript/commonjs/toast/ToastRow.d.ts +80 -0
  280. package/lib/typescript/commonjs/toast/ToastRow.d.ts.map +1 -0
  281. package/lib/typescript/commonjs/toast/ToastSwipeHandler.d.ts +30 -0
  282. package/lib/typescript/commonjs/toast/ToastSwipeHandler.d.ts.map +1 -0
  283. package/lib/typescript/commonjs/toast/Toaster.d.ts +19 -0
  284. package/lib/typescript/commonjs/toast/Toaster.d.ts.map +1 -0
  285. package/lib/typescript/commonjs/toast/animations.d.ts +62 -0
  286. package/lib/typescript/commonjs/toast/animations.d.ts.map +1 -0
  287. package/lib/typescript/commonjs/toast/constants.d.ts +39 -0
  288. package/lib/typescript/commonjs/toast/constants.d.ts.map +1 -0
  289. package/lib/typescript/commonjs/toast/context.d.ts +19 -0
  290. package/lib/typescript/commonjs/toast/context.d.ts.map +1 -0
  291. package/lib/typescript/commonjs/toast/index.d.ts +23 -76
  292. package/lib/typescript/commonjs/toast/index.d.ts.map +1 -1
  293. package/lib/typescript/commonjs/toast/position-utils.d.ts +30 -0
  294. package/lib/typescript/commonjs/toast/position-utils.d.ts.map +1 -0
  295. package/lib/typescript/commonjs/toast/positioner-utils.d.ts +72 -0
  296. package/lib/typescript/commonjs/toast/positioner-utils.d.ts.map +1 -0
  297. package/lib/typescript/commonjs/toast/toast-comparator.d.ts +12 -0
  298. package/lib/typescript/commonjs/toast/toast-comparator.d.ts.map +1 -0
  299. package/lib/typescript/commonjs/toast/toast-fns.d.ts +3 -0
  300. package/lib/typescript/commonjs/toast/toast-fns.d.ts.map +1 -0
  301. package/lib/typescript/commonjs/toast/toast-store.d.ts +52 -0
  302. package/lib/typescript/commonjs/toast/toast-store.d.ts.map +1 -0
  303. package/lib/typescript/commonjs/toast/toast-timers.d.ts +24 -0
  304. package/lib/typescript/commonjs/toast/toast-timers.d.ts.map +1 -0
  305. package/lib/typescript/commonjs/toast/types.d.ts +222 -5
  306. package/lib/typescript/commonjs/toast/types.d.ts.map +1 -1
  307. package/lib/typescript/commonjs/toast/use-animated-target.d.ts +7 -0
  308. package/lib/typescript/commonjs/toast/use-animated-target.d.ts.map +1 -0
  309. package/lib/typescript/commonjs/toast/use-app-state.d.ts +18 -0
  310. package/lib/typescript/commonjs/toast/use-app-state.d.ts.map +1 -0
  311. package/lib/typescript/commonjs/toast/use-toast-colors.d.ts +22 -0
  312. package/lib/typescript/commonjs/toast/use-toast-colors.d.ts.map +1 -0
  313. package/lib/typescript/commonjs/toast/use-toast-position.d.ts +37 -0
  314. package/lib/typescript/commonjs/toast/use-toast-position.d.ts.map +1 -0
  315. package/lib/typescript/commonjs/tooltip/index.web.d.ts.map +1 -1
  316. package/lib/typescript/commonjs/zoomable-image-gallery/ZoomableImageGallery.d.ts.map +1 -1
  317. package/lib/typescript/module/avatar-group/AvatarGroup.web.d.ts.map +1 -1
  318. package/lib/typescript/module/bottom-sheet/index.web.d.ts.map +1 -1
  319. package/lib/typescript/module/context-menu/index.web.d.ts.map +1 -1
  320. package/lib/typescript/module/dialog/Dialog.web.d.ts.map +1 -1
  321. package/lib/typescript/module/index.d.ts +2 -1
  322. package/lib/typescript/module/index.d.ts.map +1 -1
  323. package/lib/typescript/module/index.web.d.ts +2 -1
  324. package/lib/typescript/module/index.web.d.ts.map +1 -1
  325. package/lib/typescript/module/menu/index.web.d.ts.map +1 -1
  326. package/lib/typescript/module/popover/index.web.d.ts.map +1 -1
  327. package/lib/typescript/module/portal/index.d.ts.map +1 -1
  328. package/lib/typescript/module/progressive-blur/index.d.ts +23 -0
  329. package/lib/typescript/module/progressive-blur/index.d.ts.map +1 -0
  330. package/lib/typescript/module/progressive-blur/index.web.d.ts +30 -0
  331. package/lib/typescript/module/progressive-blur/index.web.d.ts.map +1 -0
  332. package/lib/typescript/module/progressive-blur/shared.d.ts +35 -0
  333. package/lib/typescript/module/progressive-blur/shared.d.ts.map +1 -0
  334. package/lib/typescript/module/progressive-blur/types.d.ts +21 -0
  335. package/lib/typescript/module/progressive-blur/types.d.ts.map +1 -0
  336. package/lib/typescript/module/select/index.web.d.ts.map +1 -1
  337. package/lib/typescript/module/styles/web-view-style.d.ts +21 -0
  338. package/lib/typescript/module/styles/web-view-style.d.ts.map +1 -0
  339. package/lib/typescript/module/tab-bar/TabBarBase.d.ts +36 -0
  340. package/lib/typescript/module/tab-bar/TabBarBase.d.ts.map +1 -0
  341. package/lib/typescript/module/tab-bar/expo-router/RouterTabBar.d.ts +59 -0
  342. package/lib/typescript/module/tab-bar/expo-router/RouterTabBar.d.ts.map +1 -0
  343. package/lib/typescript/module/tab-bar/expo-router/fading-tab-screen.d.ts +11 -0
  344. package/lib/typescript/module/tab-bar/expo-router/fading-tab-screen.d.ts.map +1 -0
  345. package/lib/typescript/module/tab-bar/expo-router/index.d.ts +14 -0
  346. package/lib/typescript/module/tab-bar/expo-router/index.d.ts.map +1 -0
  347. package/lib/typescript/module/tab-bar/glyph.d.ts +6 -0
  348. package/lib/typescript/module/tab-bar/glyph.d.ts.map +1 -0
  349. package/lib/typescript/module/tab-bar/glyph.native.d.ts +6 -0
  350. package/lib/typescript/module/tab-bar/glyph.native.d.ts.map +1 -0
  351. package/lib/typescript/module/tab-bar/index.d.ts +12 -0
  352. package/lib/typescript/module/tab-bar/index.d.ts.map +1 -0
  353. package/lib/typescript/module/tab-bar/index.web.d.ts +12 -0
  354. package/lib/typescript/module/tab-bar/index.web.d.ts.map +1 -0
  355. package/lib/typescript/module/tab-bar/minimize-context.d.ts +51 -0
  356. package/lib/typescript/module/tab-bar/minimize-context.d.ts.map +1 -0
  357. package/lib/typescript/module/tab-bar/shared.d.ts +93 -0
  358. package/lib/typescript/module/tab-bar/shared.d.ts.map +1 -0
  359. package/lib/typescript/module/tab-bar/surface.d.ts +6 -0
  360. package/lib/typescript/module/tab-bar/surface.d.ts.map +1 -0
  361. package/lib/typescript/module/tab-bar/surface.native.d.ts +6 -0
  362. package/lib/typescript/module/tab-bar/surface.native.d.ts.map +1 -0
  363. package/lib/typescript/module/tab-bar/surface.web.d.ts +6 -0
  364. package/lib/typescript/module/tab-bar/surface.web.d.ts.map +1 -0
  365. package/lib/typescript/module/tab-bar/types.d.ts +85 -0
  366. package/lib/typescript/module/tab-bar/types.d.ts.map +1 -0
  367. package/lib/typescript/module/toast/Positioner.d.ts +21 -0
  368. package/lib/typescript/module/toast/Positioner.d.ts.map +1 -0
  369. package/lib/typescript/module/toast/ToastContent.d.ts +14 -0
  370. package/lib/typescript/module/toast/ToastContent.d.ts.map +1 -0
  371. package/lib/typescript/module/toast/ToastHost.d.ts +6 -0
  372. package/lib/typescript/module/toast/ToastHost.d.ts.map +1 -0
  373. package/lib/typescript/module/toast/ToastHost.native.d.ts +6 -0
  374. package/lib/typescript/module/toast/ToastHost.native.d.ts.map +1 -0
  375. package/lib/typescript/module/toast/ToastIcon.d.ts +9 -0
  376. package/lib/typescript/module/toast/ToastIcon.d.ts.map +1 -0
  377. package/lib/typescript/module/toast/ToastRow.d.ts +80 -0
  378. package/lib/typescript/module/toast/ToastRow.d.ts.map +1 -0
  379. package/lib/typescript/module/toast/ToastSwipeHandler.d.ts +30 -0
  380. package/lib/typescript/module/toast/ToastSwipeHandler.d.ts.map +1 -0
  381. package/lib/typescript/module/toast/Toaster.d.ts +19 -0
  382. package/lib/typescript/module/toast/Toaster.d.ts.map +1 -0
  383. package/lib/typescript/module/toast/animations.d.ts +62 -0
  384. package/lib/typescript/module/toast/animations.d.ts.map +1 -0
  385. package/lib/typescript/module/toast/constants.d.ts +39 -0
  386. package/lib/typescript/module/toast/constants.d.ts.map +1 -0
  387. package/lib/typescript/module/toast/context.d.ts +19 -0
  388. package/lib/typescript/module/toast/context.d.ts.map +1 -0
  389. package/lib/typescript/module/toast/index.d.ts +23 -76
  390. package/lib/typescript/module/toast/index.d.ts.map +1 -1
  391. package/lib/typescript/module/toast/position-utils.d.ts +30 -0
  392. package/lib/typescript/module/toast/position-utils.d.ts.map +1 -0
  393. package/lib/typescript/module/toast/positioner-utils.d.ts +72 -0
  394. package/lib/typescript/module/toast/positioner-utils.d.ts.map +1 -0
  395. package/lib/typescript/module/toast/toast-comparator.d.ts +12 -0
  396. package/lib/typescript/module/toast/toast-comparator.d.ts.map +1 -0
  397. package/lib/typescript/module/toast/toast-fns.d.ts +3 -0
  398. package/lib/typescript/module/toast/toast-fns.d.ts.map +1 -0
  399. package/lib/typescript/module/toast/toast-store.d.ts +52 -0
  400. package/lib/typescript/module/toast/toast-store.d.ts.map +1 -0
  401. package/lib/typescript/module/toast/toast-timers.d.ts +24 -0
  402. package/lib/typescript/module/toast/toast-timers.d.ts.map +1 -0
  403. package/lib/typescript/module/toast/types.d.ts +222 -5
  404. package/lib/typescript/module/toast/types.d.ts.map +1 -1
  405. package/lib/typescript/module/toast/use-animated-target.d.ts +7 -0
  406. package/lib/typescript/module/toast/use-animated-target.d.ts.map +1 -0
  407. package/lib/typescript/module/toast/use-app-state.d.ts +18 -0
  408. package/lib/typescript/module/toast/use-app-state.d.ts.map +1 -0
  409. package/lib/typescript/module/toast/use-toast-colors.d.ts +22 -0
  410. package/lib/typescript/module/toast/use-toast-colors.d.ts.map +1 -0
  411. package/lib/typescript/module/toast/use-toast-position.d.ts +37 -0
  412. package/lib/typescript/module/toast/use-toast-position.d.ts.map +1 -0
  413. package/lib/typescript/module/tooltip/index.web.d.ts.map +1 -1
  414. package/lib/typescript/module/zoomable-image-gallery/ZoomableImageGallery.d.ts.map +1 -1
  415. package/package.json +63 -25
  416. package/src/__tests__/TabBar.test.tsx +342 -0
  417. package/src/__tests__/TabBarReanimatedDeps.test.ts +130 -0
  418. package/src/__tests__/TabBarWebFork.test.ts +197 -0
  419. package/src/__tests__/ToastContent.test.tsx +192 -0
  420. package/src/__tests__/ToastHostWebFork.test.ts +155 -0
  421. package/src/__tests__/Toaster.test.tsx +527 -0
  422. package/src/__tests__/animated-style-deps.test.ts +156 -0
  423. package/src/__tests__/toast-animations.test.ts +98 -0
  424. package/src/__tests__/toast-comparator.test.ts +131 -0
  425. package/src/__tests__/toast-enter-driver.test.ts +147 -0
  426. package/src/__tests__/toast-fns.test.ts +240 -0
  427. package/src/__tests__/toast-position-utils.test.ts +259 -0
  428. package/src/__tests__/toast-positioner-utils.test.ts +214 -0
  429. package/src/__tests__/toast-store.test.ts +622 -0
  430. package/src/__tests__/toast-timers.test.ts +163 -0
  431. package/src/__tests__/use-animated-target.test.tsx +60 -0
  432. package/src/__tests__/use-app-state.test.tsx +127 -0
  433. package/src/__tests__/use-toast-colors.test.tsx +189 -0
  434. package/src/__tests__/web-position-fixed.test.ts +70 -0
  435. package/src/avatar-group/AvatarGroup.web.tsx +2 -1
  436. package/src/bottom-sheet/index.web.tsx +3 -2
  437. package/src/context-menu/index.web.tsx +3 -2
  438. package/src/dialog/Dialog.web.tsx +4 -3
  439. package/src/index.ts +4 -1
  440. package/src/index.web.ts +4 -1
  441. package/src/menu/index.web.tsx +2 -1
  442. package/src/popover/index.web.tsx +3 -2
  443. package/src/portal/index.tsx +4 -1
  444. package/src/progressive-blur/index.tsx +78 -0
  445. package/src/progressive-blur/index.web.tsx +65 -0
  446. package/src/progressive-blur/shared.ts +81 -0
  447. package/src/progressive-blur/types.ts +21 -0
  448. package/src/select/index.web.tsx +2 -1
  449. package/src/styles/web-view-style.ts +21 -0
  450. package/src/tab-bar/TabBar.stories.tsx +217 -0
  451. package/src/tab-bar/TabBarBase.tsx +517 -0
  452. package/src/tab-bar/expo-router/RouterTabBar.tsx +80 -0
  453. package/src/tab-bar/expo-router/fading-tab-screen.tsx +109 -0
  454. package/src/tab-bar/expo-router/index.ts +13 -0
  455. package/src/tab-bar/glyph.native.tsx +46 -0
  456. package/src/tab-bar/glyph.tsx +31 -0
  457. package/src/tab-bar/index.ts +32 -0
  458. package/src/tab-bar/index.web.tsx +34 -0
  459. package/src/tab-bar/minimize-context.tsx +117 -0
  460. package/src/tab-bar/shared.ts +159 -0
  461. package/src/tab-bar/surface.native.tsx +60 -0
  462. package/src/tab-bar/surface.tsx +47 -0
  463. package/src/tab-bar/surface.web.tsx +56 -0
  464. package/src/tab-bar/types.ts +88 -0
  465. package/src/toast/Positioner.tsx +121 -0
  466. package/src/toast/Toast.stories.tsx +292 -65
  467. package/src/toast/ToastContent.tsx +405 -0
  468. package/src/toast/ToastHost.native.tsx +31 -0
  469. package/src/toast/ToastHost.tsx +67 -0
  470. package/src/toast/ToastIcon.tsx +55 -0
  471. package/src/toast/ToastRow.tsx +485 -0
  472. package/src/toast/ToastSwipeHandler.tsx +222 -0
  473. package/src/toast/Toaster.tsx +259 -0
  474. package/src/toast/animations.ts +313 -0
  475. package/src/toast/constants.ts +76 -0
  476. package/src/toast/context.tsx +44 -0
  477. package/src/toast/index.tsx +47 -123
  478. package/src/toast/position-utils.ts +149 -0
  479. package/src/toast/positioner-utils.ts +142 -0
  480. package/src/toast/toast-comparator.ts +41 -0
  481. package/src/toast/toast-fns.ts +104 -0
  482. package/src/toast/toast-store.ts +432 -0
  483. package/src/toast/toast-timers.ts +124 -0
  484. package/src/toast/types.ts +301 -5
  485. package/src/toast/use-animated-target.ts +61 -0
  486. package/src/toast/use-app-state.ts +77 -0
  487. package/src/toast/use-toast-colors.ts +133 -0
  488. package/src/toast/use-toast-position.ts +46 -0
  489. package/src/tooltip/index.web.tsx +2 -1
  490. package/src/zoomable-image-gallery/ZoomableImageGallery.stories.tsx +134 -0
  491. package/src/zoomable-image-gallery/ZoomableImageGallery.tsx +50 -27
  492. package/lib/commonjs/toast/Toast.js +0 -267
  493. package/lib/commonjs/toast/Toast.js.map +0 -1
  494. package/lib/commonjs/toast/const.js +0 -8
  495. package/lib/commonjs/toast/const.js.map +0 -1
  496. package/lib/commonjs/toast/index.web.js +0 -114
  497. package/lib/commonjs/toast/index.web.js.map +0 -1
  498. package/lib/commonjs/toast/sonner/index.js +0 -9
  499. package/lib/commonjs/toast/sonner/index.js.map +0 -1
  500. package/lib/commonjs/toast/sonner/index.web.js +0 -9
  501. package/lib/commonjs/toast/sonner/index.web.js.map +0 -1
  502. package/lib/module/toast/Toast.js +0 -258
  503. package/lib/module/toast/Toast.js.map +0 -1
  504. package/lib/module/toast/const.js +0 -4
  505. package/lib/module/toast/const.js.map +0 -1
  506. package/lib/module/toast/index.web.js +0 -74
  507. package/lib/module/toast/index.web.js.map +0 -1
  508. package/lib/module/toast/sonner/index.js +0 -5
  509. package/lib/module/toast/sonner/index.js.map +0 -1
  510. package/lib/module/toast/sonner/index.web.js +0 -5
  511. package/lib/module/toast/sonner/index.web.js.map +0 -1
  512. package/lib/typescript/commonjs/toast/Toast.d.ts +0 -23
  513. package/lib/typescript/commonjs/toast/Toast.d.ts.map +0 -1
  514. package/lib/typescript/commonjs/toast/const.d.ts +0 -2
  515. package/lib/typescript/commonjs/toast/const.d.ts.map +0 -1
  516. package/lib/typescript/commonjs/toast/index.web.d.ts +0 -29
  517. package/lib/typescript/commonjs/toast/index.web.d.ts.map +0 -1
  518. package/lib/typescript/commonjs/toast/sonner/index.d.ts +0 -2
  519. package/lib/typescript/commonjs/toast/sonner/index.d.ts.map +0 -1
  520. package/lib/typescript/commonjs/toast/sonner/index.web.d.ts +0 -2
  521. package/lib/typescript/commonjs/toast/sonner/index.web.d.ts.map +0 -1
  522. package/lib/typescript/module/toast/Toast.d.ts +0 -23
  523. package/lib/typescript/module/toast/Toast.d.ts.map +0 -1
  524. package/lib/typescript/module/toast/const.d.ts +0 -2
  525. package/lib/typescript/module/toast/const.d.ts.map +0 -1
  526. package/lib/typescript/module/toast/index.web.d.ts +0 -29
  527. package/lib/typescript/module/toast/index.web.d.ts.map +0 -1
  528. package/lib/typescript/module/toast/sonner/index.d.ts +0 -2
  529. package/lib/typescript/module/toast/sonner/index.d.ts.map +0 -1
  530. package/lib/typescript/module/toast/sonner/index.web.d.ts +0 -2
  531. package/lib/typescript/module/toast/sonner/index.web.d.ts.map +0 -1
  532. package/src/toast/Toast.tsx +0 -269
  533. package/src/toast/const.ts +0 -1
  534. package/src/toast/index.web.tsx +0 -101
  535. package/src/toast/sonner/index.ts +0 -3
  536. package/src/toast/sonner/index.web.ts +0 -3
@@ -21,6 +21,7 @@ import { RemoveScrollBar } from 'react-remove-scroll-bar';
21
21
 
22
22
  import { Portal } from '../portal/index.web';
23
23
  import { createOverlayZIndex } from '../styles/z-index';
24
+ import { WEB_POSITION_FIXED } from '../styles/web-view-style';
24
25
  import { bloomShadowStyle } from '../design-tokens/shadows';
25
26
  import { useTheme } from '../theme/use-theme';
26
27
  import { Context, useDialogContext, useDialogControl } from './context';
@@ -304,7 +305,7 @@ function CenterOrSideDialog({
304
305
  // `pointer-events: none`, which is set so the idle portal
305
306
  // doesn't intercept clicks on the underlying app.
306
307
  style={{
307
- position: 'fixed' as 'absolute',
308
+ position: WEB_POSITION_FIXED,
308
309
  top: 0,
309
310
  left: 0,
310
311
  right: 0,
@@ -790,7 +791,7 @@ function cancelFrame(token: FrameToken): void {
790
791
  function DialogBackdrop({ isClosing }: { isClosing: boolean }) {
791
792
  const style: ViewStyle[] = [
792
793
  {
793
- position: 'fixed' as 'absolute',
794
+ position: WEB_POSITION_FIXED,
794
795
  top: 0,
795
796
  left: 0,
796
797
  right: 0,
@@ -843,7 +844,7 @@ const sheetStyles = {
843
844
  // the per-layer `createOverlayZIndex(layer)` in `SheetSurface`, so a side
844
845
  // dialog stacked on top of another (surface stack) paints above it.
845
846
  root: {
846
- position: 'fixed' as 'absolute',
847
+ position: WEB_POSITION_FIXED,
847
848
  top: 0,
848
849
  left: 0,
849
850
  right: 0,
package/src/index.ts CHANGED
@@ -112,7 +112,10 @@ export type { UserHoverCardProps, UserHoverCardStat } from './user-hover-card';
112
112
  export * from './loading';
113
113
  export * from './prompt-input';
114
114
  export * from './switch';
115
- export { toast, type Toast } from './toast';
115
+ // `ToastOutlet` is a required app-root mount, like `BloomDialogProvider` and
116
+ // `SurfaceHost`. The full engine surface lives at `@oxyhq/bloom/toast`.
117
+ export { toast, ToastOutlet } from './toast';
118
+ export type { ToastFn, ToastOptions, ToastType } from './toast';
116
119
 
117
120
  // Typography
118
121
  export * as Typography from './typography';
package/src/index.web.ts CHANGED
@@ -117,7 +117,10 @@ export type { UserHoverCardProps, UserHoverCardStat } from './user-hover-card';
117
117
  export * from './loading/index.web';
118
118
  export * from './prompt-input';
119
119
  export * from './switch';
120
- export { toast, type Toast } from './toast/index.web';
120
+ // `ToastOutlet` is a required app-root mount, like `BloomDialogProvider` and
121
+ // `SurfaceHost`. The full engine surface lives at `@oxyhq/bloom/toast`.
122
+ export { toast, ToastOutlet } from './toast';
123
+ export type { ToastFn, ToastOptions, ToastType } from './toast';
121
124
 
122
125
  // Typography
123
126
  export * as Typography from './typography';
@@ -17,6 +17,7 @@ import { Text } from '../typography';
17
17
  import type { DialogControlProps } from '../dialog/types';
18
18
  import { Portal } from '../portal/index.web';
19
19
  import { createDropdownZIndex } from '../styles/z-index';
20
+ import { WEB_POSITION_FIXED } from '../styles/web-view-style';
20
21
  import { bloomShadowStyle } from '../design-tokens/shadows';
21
22
  import {
22
23
  MenuContext,
@@ -222,7 +223,7 @@ export function MenuContent({
222
223
  );
223
224
 
224
225
  setPosition({
225
- position: 'fixed' as 'absolute',
226
+ position: WEB_POSITION_FIXED,
226
227
  top,
227
228
  left,
228
229
  right: undefined,
@@ -12,6 +12,7 @@ import { Pressable, StyleSheet, View } from 'react-native';
12
12
  import { useTheme } from '../theme/use-theme';
13
13
  import { Portal } from '../portal/index.web';
14
14
  import { createOverlayZIndex } from '../styles/z-index';
15
+ import { WEB_POSITION_FIXED } from '../styles/web-view-style';
15
16
  import { bloomShadowStyle } from '../design-tokens/shadows';
16
17
  import { PopoverContext, usePopoverContext } from './context';
17
18
  import type {
@@ -308,7 +309,7 @@ const styles = StyleSheet.create({
308
309
  alignSelf: 'flex-start',
309
310
  },
310
311
  backdrop: {
311
- position: 'fixed' as 'absolute',
312
+ position: WEB_POSITION_FIXED,
312
313
  top: 0,
313
314
  left: 0,
314
315
  right: 0,
@@ -317,7 +318,7 @@ const styles = StyleSheet.create({
317
318
  pointerEvents: 'auto',
318
319
  },
319
320
  panel: {
320
- position: 'fixed' as 'absolute',
321
+ position: WEB_POSITION_FIXED,
321
322
  zIndex: popoverZIndex.surface,
322
323
  borderRadius: 12,
323
324
  borderWidth: 1,
@@ -12,6 +12,7 @@ import React, {
12
12
  } from 'react';
13
13
  import { View, StyleSheet, Platform } from 'react-native';
14
14
  import { Z_INDEX } from '../styles/z-index';
15
+ import { WEB_POSITION_FIXED } from '../styles/web-view-style';
15
16
 
16
17
  type Component = React.ReactElement;
17
18
 
@@ -114,8 +115,10 @@ export const Outlet = memo(DefaultPortal.Outlet);
114
115
  export const Portal = DefaultPortal.Portal;
115
116
 
116
117
  const styles = StyleSheet.create({
118
+ // Applied only from the `Platform.OS === 'web'` branch of `Outlet`, which is
119
+ // why the web-only `position` value is honest in this universal file.
117
120
  portalOutlet: {
118
- position: 'fixed' as 'absolute',
121
+ position: WEB_POSITION_FIXED,
119
122
  top: 0,
120
123
  left: 0,
121
124
  right: 0,
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Ported from expo-glass-tabs v0.1.1 — src/progressive-blur.tsx
3
+ * (MIT © 2026 David Mokos). See the top-level NOTICE.
4
+ */
5
+ import { BlurView } from 'expo-blur';
6
+ import { StyleSheet, View } from 'react-native';
7
+
8
+ import { useTheme } from '../theme/use-theme';
9
+ import { buildTailGradient, LAYER_HEIGHTS } from './shared';
10
+ import type { ProgressiveBlurProps } from './types';
11
+
12
+ export type { ProgressiveBlurProps } from './types';
13
+
14
+ /**
15
+ * Progressive (gradient) blur: strongest at the anchored edge, fading to none.
16
+ * Drop it behind a floating tab bar or a transparent header so content
17
+ * dissolves rather than meeting a hard blur line.
18
+ *
19
+ * NATIVE implementation. iOS has no public variable-blur API, so this stacks
20
+ * ten thin `BlurView`s with a tiny per-layer intensity — each layer's edge adds
21
+ * only an imperceptible step, so the falloff reads as continuous (see
22
+ * `LAYER_HEIGHTS`). A soft gradient in the theme's page color smooths the tail
23
+ * and keeps overlaid content legible.
24
+ *
25
+ * The web fork replaces the whole stack with one masked `backdrop-filter`:
26
+ * `experimental_backgroundImage` is dropped silently by react-native-web, and
27
+ * ten stacked backdrop passes would be far more expensive than the one the
28
+ * browser can do natively.
29
+ */
30
+ export function ProgressiveBlur({
31
+ style,
32
+ intensity = 5,
33
+ direction = 'top',
34
+ ...rest
35
+ }: ProgressiveBlurProps) {
36
+ const { colors, isDark } = useTheme();
37
+ const anchor = direction === 'top' ? styles.anchorTop : styles.anchorBottom;
38
+
39
+ return (
40
+ <View {...rest} style={[styles.root, style]}>
41
+ {LAYER_HEIGHTS.map((height) => (
42
+ <BlurView
43
+ key={height}
44
+ tint={isDark ? 'dark' : 'light'}
45
+ intensity={intensity}
46
+ style={[styles.layer, anchor, { height }]}
47
+ />
48
+ ))}
49
+ <View
50
+ style={[
51
+ StyleSheet.absoluteFill,
52
+ { experimental_backgroundImage: buildTailGradient(colors.background, direction) },
53
+ ]}
54
+ />
55
+ </View>
56
+ );
57
+ }
58
+
59
+ ProgressiveBlur.displayName = 'ProgressiveBlur';
60
+
61
+ const styles = StyleSheet.create({
62
+ root: {
63
+ // In the style object, not as a prop: RN-Web deprecated the `pointerEvents`
64
+ // prop and warns on every render when it is used.
65
+ pointerEvents: 'none',
66
+ },
67
+ layer: {
68
+ position: 'absolute',
69
+ left: 0,
70
+ right: 0,
71
+ },
72
+ anchorTop: {
73
+ top: 0,
74
+ },
75
+ anchorBottom: {
76
+ bottom: 0,
77
+ },
78
+ });
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Ported from expo-glass-tabs v0.1.1 — src/progressive-blur.tsx
3
+ * (MIT © 2026 David Mokos). See the top-level NOTICE.
4
+ */
5
+ import { View, type ViewStyle } from 'react-native';
6
+
7
+ import { useTheme } from '../theme/use-theme';
8
+ import {
9
+ buildMaskGradient,
10
+ buildTailGradient,
11
+ WEB_BLUR_PER_INTENSITY,
12
+ } from './shared';
13
+ import type { ProgressiveBlurProps } from './types';
14
+
15
+ export type { ProgressiveBlurProps } from './types';
16
+
17
+ /**
18
+ * WEB fork of {@link ProgressiveBlur} — ONE element instead of the native
19
+ * ten-layer stack.
20
+ *
21
+ * Two upstream techniques do not survive a browser, which is the whole reason
22
+ * this fork exists:
23
+ *
24
+ * - `experimental_backgroundImage` is dropped silently by react-native-web
25
+ * (no warning, no gradient), so the tail is painted with real CSS
26
+ * `background-image` instead;
27
+ * - stacking ten `BlurView`s would mean ten composited backdrop passes over
28
+ * the same pixels every frame. A browser can fade a single
29
+ * `backdrop-filter` with `mask-image`, which is both correct and an order
30
+ * of magnitude cheaper.
31
+ *
32
+ * The declarations ride in the STYLE object rather than an injected CSS class:
33
+ * react-native-web does not forward `className` to the DOM (it is absent from
34
+ * its `forwardedProps` list, and `createDOMProps` overwrites the attribute with
35
+ * the atomic class it generates), while unknown style properties ARE passed
36
+ * through its style compiler — the same route `Dialog.web.tsx` uses for its
37
+ * `animation` shorthand. Nothing here needs `@keyframes` or a pseudo-class, so
38
+ * there is no stylesheet to inject and nothing a consumer could forget to wire.
39
+ */
40
+ export function ProgressiveBlur({
41
+ style,
42
+ intensity = 5,
43
+ direction = 'top',
44
+ ...rest
45
+ }: ProgressiveBlurProps) {
46
+ const { colors } = useTheme();
47
+
48
+ const filter = `blur(${intensity * WEB_BLUR_PER_INTENSITY}px)`;
49
+ const mask = buildMaskGradient(direction);
50
+ // Web-only CSS, unknown to React Native's `ViewStyle`. Both spellings are set
51
+ // for `backdrop-filter` and `mask-image`: Safari still needs the prefixed
52
+ // form of each.
53
+ const webStyle = {
54
+ pointerEvents: 'none',
55
+ backdropFilter: filter,
56
+ WebkitBackdropFilter: filter,
57
+ maskImage: mask,
58
+ WebkitMaskImage: mask,
59
+ backgroundImage: buildTailGradient(colors.background, direction),
60
+ } as ViewStyle;
61
+
62
+ return <View {...rest} style={[webStyle, style]} />;
63
+ }
64
+
65
+ ProgressiveBlur.displayName = 'ProgressiveBlur';
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Ported from expo-glass-tabs v0.1.1 — src/progressive-blur.tsx
3
+ * (MIT © 2026 David Mokos). See the top-level NOTICE.
4
+ *
5
+ * The falloff math both forks share, so the native stack and the web mask
6
+ * describe the SAME curve and a bar looks the same on a phone and in a browser.
7
+ */
8
+ import { withAlpha } from '../theme/color-utils';
9
+
10
+ /**
11
+ * Per-layer heights of the native blur stack, as a fraction of the box.
12
+ *
13
+ * iOS has no public variable-blur API, so the native fork stacks many thin
14
+ * `BlurView`s with a tiny per-layer intensity: each layer's edge adds only an
15
+ * imperceptible step, so the falloff reads as continuous. Coverage at a given
16
+ * depth is the number of layers still tall enough to reach it — 10 at the
17
+ * anchored edge, ~5 at the midpoint, 1 at the far edge.
18
+ */
19
+ export const LAYER_HEIGHTS = [
20
+ '100%',
21
+ '88%',
22
+ '76%',
23
+ '64%',
24
+ '54%',
25
+ '44%',
26
+ '36%',
27
+ '28%',
28
+ '22%',
29
+ '16%',
30
+ ] as const;
31
+
32
+ /**
33
+ * px of CSS blur per unit of `intensity` on web.
34
+ *
35
+ * The web fork replaces the whole stack with ONE `backdrop-filter`, so the
36
+ * radius has to stand in for the accumulated effect of ten layers rather than
37
+ * one: the default `intensity` of 5 lands on a 20px radius, which reads like
38
+ * the native stack at the anchored edge. Stacking ten real blurs in a browser
39
+ * would cost ten composited backdrop passes for the same picture.
40
+ */
41
+ export const WEB_BLUR_PER_INTENSITY = 4;
42
+
43
+ /** CSS gradient direction keyword for a blur anchored at `direction`. */
44
+ function towards(direction: 'top' | 'bottom'): 'top' | 'bottom' {
45
+ return direction === 'top' ? 'bottom' : 'top';
46
+ }
47
+
48
+ /**
49
+ * The soft tint layered over the blur. It smooths the tail and keeps overlaid
50
+ * content legible; upstream hardcoded black, which only worked on a dark theme,
51
+ * so it is derived from the theme's page background here instead.
52
+ */
53
+ export function buildTailGradient(background: string, direction: 'top' | 'bottom'): string {
54
+ const to = towards(direction);
55
+ return (
56
+ `linear-gradient(to ${to}, ` +
57
+ `${withAlpha(background, 0.7)} 0%, ` +
58
+ `${withAlpha(background, 0.32)} 42%, ` +
59
+ `${withAlpha(background, 0.08)} 68%, ` +
60
+ `${withAlpha(background, 0)} 88%)`
61
+ );
62
+ }
63
+
64
+ /**
65
+ * Alpha ramp the web fork masks its single blur with — the only way to fade a
66
+ * `backdrop-filter`. The stops trace the native stack's layer coverage (full at
67
+ * the anchored edge, ~half at the midpoint) and then close all the way to zero,
68
+ * which the stack cannot do: its tallest layer spans the whole box, leaving a
69
+ * faint blur step at the far edge.
70
+ */
71
+ export function buildMaskGradient(direction: 'top' | 'bottom'): string {
72
+ const to = towards(direction);
73
+ return (
74
+ `linear-gradient(to ${to}, ` +
75
+ `rgba(0, 0, 0, 1) 0%, ` +
76
+ `rgba(0, 0, 0, 0.9) 20%, ` +
77
+ `rgba(0, 0, 0, 0.5) 50%, ` +
78
+ `rgba(0, 0, 0, 0.2) 80%, ` +
79
+ `rgba(0, 0, 0, 0) 100%)`
80
+ );
81
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Ported from expo-glass-tabs v0.1.1 — src/progressive-blur.tsx
3
+ * (MIT © 2026 David Mokos). See the top-level NOTICE.
4
+ *
5
+ * Shared prop contract for both forks. It lives in its own module so the web
6
+ * fork can declare it without importing the native entry (`./index` resolves to
7
+ * `index.web.tsx` itself on a web-platform Metro build), and so `TabBarBase`
8
+ * can type its injected `Blur` component without importing either fork.
9
+ */
10
+ import type { ViewProps } from 'react-native';
11
+
12
+ export type ProgressiveBlurProps = ViewProps & {
13
+ /**
14
+ * Blur strength at the anchored edge. Follows `expo-blur`'s 0–100 scale and
15
+ * is applied PER LAYER on native (see the native fork); the web fork maps it
16
+ * onto the single CSS blur radius that approximates the same stack.
17
+ */
18
+ intensity?: number;
19
+ /** Which edge the blur is anchored to (strongest there, fading away). */
20
+ direction?: 'top' | 'bottom';
21
+ };
@@ -5,6 +5,7 @@ import { useTheme } from '../theme/use-theme';
5
5
  import { Text } from '../typography';
6
6
  import { Portal } from '../portal/index.web';
7
7
  import { createOverlayZIndex } from '../styles/z-index';
8
+ import { WEB_POSITION_FIXED } from '../styles/web-view-style';
8
9
  import { bloomShadowStyle } from '../design-tokens/shadows';
9
10
  import { RadioIndicator } from '../radio-indicator';
10
11
  import { useInteractionState } from '../hooks/useInteractionState';
@@ -332,7 +333,7 @@ const styles = StyleSheet.create({
332
333
  fontSize: 16,
333
334
  },
334
335
  backdrop: {
335
- position: 'fixed' as 'absolute',
336
+ position: WEB_POSITION_FIXED,
336
337
  top: 0,
337
338
  left: 0,
338
339
  right: 0,
@@ -0,0 +1,21 @@
1
+ import type { ViewStyle } from 'react-native';
2
+
3
+ /**
4
+ * `position: fixed`, typed for React Native's `ViewStyle`.
5
+ *
6
+ * RN types `position` as `'absolute' | 'relative' | 'static'` — what Yoga
7
+ * implements — while react-native-web renders real CSS, where `'fixed'` is the
8
+ * only way for a portaled overlay to anchor to the VIEWPORT instead of the
9
+ * nearest positioned ancestor. This is the ONE place Bloom crosses between the
10
+ * two, so web forks import it instead of writing their own cast.
11
+ *
12
+ * Deliberately not a `declare module 'react-native'` augmentation, for two
13
+ * reasons. It does not work: `position` lives on `interface FlexStyle`, which RN
14
+ * re-exports from a submodule, so augmenting `'react-native'` neither merges nor
15
+ * errors — verified with tsc, the identical `TS2322` appears with and without it,
16
+ * which makes it strictly worse than a cast because it looks like a fix. And even
17
+ * if it worked, widening `ViewStyle` would ship through `/// <reference path>` to
18
+ * every consumer, so `position: 'fixed'` would start compiling in NATIVE code
19
+ * where Yoga silently ignores it.
20
+ */
21
+ export const WEB_POSITION_FIXED = 'fixed' as ViewStyle['position'];
@@ -0,0 +1,217 @@
1
+ import React, { useState, type PropsWithChildren } from 'react';
2
+ import { ScrollView, Text, View } from 'react-native';
3
+ import { GestureHandlerRootView } from 'react-native-gesture-handler';
4
+ import Animated from 'react-native-reanimated';
5
+ import { SafeAreaProvider } from 'react-native-safe-area-context';
6
+ import type { Meta, StoryObj } from '@storybook/react-vite';
7
+
8
+ import * as Icons from '../icons';
9
+ import { useTheme } from '../theme/use-theme';
10
+ import { TabBar, TabBarButton, TabBarMinimizeProvider, useMinimizeOnScroll } from './index';
11
+ import type { TabBarItem, TabBarProps } from './types';
12
+
13
+ /**
14
+ * The floating tab bar, on the ROUTER-FREE core (`activeIndex` /
15
+ * `onIndexChange`). No expo-router anywhere — that is the point of the core
16
+ * layer, and it is what lets the family be exercised in a plain web bundle.
17
+ *
18
+ * Storybook resolves `./index` through its `.web.*`-first extension list, so
19
+ * these stories run the WEB fork (`surface.web.tsx`'s `backdrop-filter` glass
20
+ * and `progressive-blur/index.web.tsx`) against the REAL reanimated,
21
+ * gesture-handler and safe-area-context — no worklets babel plugin, exactly
22
+ * what every Oxy RN-Web app ships. That makes every animated path here
23
+ * observable rather than assumed:
24
+ *
25
+ * - **tap / scrub**: the highlight springs to the tapped tab, and follows the
26
+ * finger 1:1 while dragging across the bar
27
+ * - **minimize**: scrolling down shrinks the pill and fades the labels out
28
+ * - **glyph crossfade**: the active tint tracks the highlight, not the tap
29
+ *
30
+ * All of them are driven by shared values read inside `useAnimatedStyle`
31
+ * mappers, so if a dependency array is ever dropped (the web freeze-at-first-
32
+ * frame failure mode documented in `TabBarBase`) these stories visibly stop
33
+ * moving while nothing errors.
34
+ */
35
+ const meta: Meta<typeof TabBar> = {
36
+ title: 'Components/TabBar',
37
+ component: TabBar,
38
+ // The bar is a screen-level element: its highlight geometry comes from
39
+ // `useWindowDimensions()`, so the demo has to be exactly window-wide or the
40
+ // pill drifts out of step with the tabs and reads as a component bug.
41
+ // `fullscreen` drops Storybook's own canvas padding; the preview decorator's
42
+ // padding is cancelled by `Screen`'s negative margin.
43
+ parameters: { layout: 'fullscreen' },
44
+ };
45
+
46
+ export default meta;
47
+
48
+ type Story = StoryObj<typeof TabBar>;
49
+
50
+ const ITEMS: TabBarItem[] = [
51
+ { name: 'home', label: 'Home', icon: <Icons.Home_Stroke2_Corner0_Rounded /> },
52
+ { name: 'search', label: 'Search', icon: <Icons.MagnifyingGlass_Stroke2_Corner0_Rounded /> },
53
+ { name: 'inbox', label: 'Inbox', icon: <Icons.Message_Stroke2_Corner0_Rounded /> },
54
+ { name: 'profile', label: 'Profile', icon: <Icons.Person_Stroke2_Corner0_Rounded /> },
55
+ ];
56
+
57
+ /** Padding the preview decorator puts around every story (`.storybook/preview.tsx`). */
58
+ const PREVIEW_PADDING = 24;
59
+ /** Height of the demo viewport — a phone-ish screen for the bar to float over. */
60
+ const SCREEN_HEIGHT = 560;
61
+ /** Keeps the last rows scrollable clear of the pill. */
62
+ const CONTENT_BOTTOM_PAD = 140;
63
+
64
+ const ROWS = Array.from({ length: 18 }, (_, index) => index + 1);
65
+
66
+ /**
67
+ * The demo viewport.
68
+ *
69
+ * It bleeds past the preview decorator's padding on purpose: the bar is a
70
+ * screen-level element and derives its highlight geometry from
71
+ * `useWindowDimensions()`, so anything narrower than the window would put the
72
+ * pill out of step with the tabs and look like a component bug.
73
+ *
74
+ * `SafeAreaProvider` is here because `TabBar` reads safe-area insets to sit
75
+ * above the home indicator; a consuming app already has one at its root, the
76
+ * Storybook preview does not.
77
+ */
78
+ function Screen({ children }: PropsWithChildren) {
79
+ const { colors } = useTheme();
80
+ return (
81
+ <SafeAreaProvider
82
+ style={{ flex: 0, alignSelf: 'stretch', marginHorizontal: -PREVIEW_PADDING }}
83
+ >
84
+ <GestureHandlerRootView
85
+ style={{
86
+ height: SCREEN_HEIGHT,
87
+ backgroundColor: colors.background,
88
+ overflow: 'hidden',
89
+ }}
90
+ >
91
+ {children}
92
+ </GestureHandlerRootView>
93
+ </SafeAreaProvider>
94
+ );
95
+ }
96
+
97
+ /** Tall themed filler so there is something for the bar to float over — and to scroll. */
98
+ function Feed({ heading, caption }: { heading: string; caption: string }) {
99
+ const { colors } = useTheme();
100
+ return (
101
+ <>
102
+ <Text style={{ color: colors.text, fontSize: 24, fontWeight: '700' }}>{heading}</Text>
103
+ <Text style={{ color: colors.textSecondary, fontSize: 14 }}>{caption}</Text>
104
+ {ROWS.map((row) => (
105
+ <View
106
+ key={row}
107
+ style={{
108
+ padding: 16,
109
+ borderRadius: 16,
110
+ borderWidth: 1,
111
+ borderColor: colors.border,
112
+ backgroundColor: colors.backgroundSecondary,
113
+ gap: 4,
114
+ }}
115
+ >
116
+ <Text style={{ color: colors.text, fontSize: 15, fontWeight: '600' }}>Item {row}</Text>
117
+ <Text style={{ color: colors.textSecondary, fontSize: 13 }}>
118
+ Scrolls under the glass so the surface has something to refract.
119
+ </Text>
120
+ </View>
121
+ ))}
122
+ </>
123
+ );
124
+ }
125
+
126
+ const CONTENT_STYLE = { padding: 16, paddingBottom: CONTENT_BOTTOM_PAD, gap: 12 } as const;
127
+
128
+ /** Controlled core: local state in, `onIndexChange` out. No router involved. */
129
+ function ControlledBar(props: TabBarProps) {
130
+ return (
131
+ <TabBar {...props}>
132
+ {ITEMS.map((item, index) => (
133
+ <TabBarButton key={item.name} item={item} index={index} />
134
+ ))}
135
+ </TabBar>
136
+ );
137
+ }
138
+
139
+ function DefaultScreen() {
140
+ const [activeIndex, setActiveIndex] = useState(0);
141
+ return (
142
+ <Screen>
143
+ <ScrollView contentContainerStyle={CONTENT_STYLE}>
144
+ <Feed
145
+ heading={ITEMS[activeIndex]?.label ?? 'Feed'}
146
+ caption="Tap a tab, or press and drag across the bar to scrub the highlight."
147
+ />
148
+ </ScrollView>
149
+ <ControlledBar activeIndex={activeIndex} onIndexChange={setActiveIndex} />
150
+ </Screen>
151
+ );
152
+ }
153
+
154
+ /**
155
+ * Body of {@link MinimizeOnScroll} — a separate component because
156
+ * `useMinimizeOnScroll()` has to run INSIDE `TabBarMinimizeProvider` to share
157
+ * the bar's progress value. Called outside it, the hook silently falls back to
158
+ * its own local shared value and nothing minimizes.
159
+ */
160
+ function MinimizeScreen() {
161
+ const [activeIndex, setActiveIndex] = useState(0);
162
+ const onScroll = useMinimizeOnScroll();
163
+ return (
164
+ <Screen>
165
+ <Animated.ScrollView
166
+ onScroll={onScroll}
167
+ scrollEventThrottle={16}
168
+ contentContainerStyle={CONTENT_STYLE}
169
+ >
170
+ <Feed
171
+ heading="Minimize on scroll"
172
+ caption="Scroll down: the pill shrinks in both dimensions and the labels fade out. Scroll up, or tap a tab, and it expands again."
173
+ />
174
+ </Animated.ScrollView>
175
+ <ControlledBar activeIndex={activeIndex} onIndexChange={setActiveIndex} />
176
+ </Screen>
177
+ );
178
+ }
179
+
180
+ function ThemeOverrideScreen() {
181
+ const { colors } = useTheme();
182
+ const [activeIndex, setActiveIndex] = useState(1);
183
+ return (
184
+ <Screen>
185
+ <ScrollView contentContainerStyle={CONTENT_STYLE}>
186
+ <Feed
187
+ heading="Theme override"
188
+ caption="Only the highlight and the active tint are overridden — the inactive tint, the glass tint and the solid fallback still come from the active preset."
189
+ />
190
+ </ScrollView>
191
+ <ControlledBar
192
+ activeIndex={activeIndex}
193
+ onIndexChange={setActiveIndex}
194
+ theme={{ highlight: colors.primary, activeTint: colors.primaryForeground }}
195
+ />
196
+ </Screen>
197
+ );
198
+ }
199
+
200
+ /** Four tabs, controlled highlight, floating over scrollable content. */
201
+ export const Default: Story = {
202
+ render: () => <DefaultScreen />,
203
+ };
204
+
205
+ /** The Revolut-style minimize: the shared progress value driven by a scroll handler. */
206
+ export const MinimizeOnScroll: Story = {
207
+ render: () => (
208
+ <TabBarMinimizeProvider>
209
+ <MinimizeScreen />
210
+ </TabBarMinimizeProvider>
211
+ ),
212
+ };
213
+
214
+ /** A partial `theme` override on top of the token-derived defaults. */
215
+ export const ThemeOverride: Story = {
216
+ render: () => <ThemeOverrideScreen />,
217
+ };