@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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxyhq/bloom",
3
- "version": "0.50.2",
3
+ "version": "0.51.0",
4
4
  "description": "Bloom UI — Oxy ecosystem component library for React Native + Expo + Web",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",
@@ -334,11 +334,6 @@
334
334
  },
335
335
  "./toast": {
336
336
  "react-native": "./src/toast/index.tsx",
337
- "browser": {
338
- "types": "./lib/typescript/module/toast/index.web.d.ts",
339
- "import": "./lib/module/toast/index.web.js",
340
- "require": "./lib/commonjs/toast/index.web.js"
341
- },
342
337
  "import": {
343
338
  "types": "./lib/typescript/module/toast/index.d.ts",
344
339
  "default": "./lib/module/toast/index.js"
@@ -1012,12 +1007,56 @@
1012
1007
  "default": "./lib/commonjs/list/index.js"
1013
1008
  }
1014
1009
  },
1010
+ "./tab-bar": {
1011
+ "react-native": "./src/tab-bar/index.ts",
1012
+ "browser": {
1013
+ "types": "./lib/typescript/module/tab-bar/index.web.d.ts",
1014
+ "import": "./lib/module/tab-bar/index.web.js",
1015
+ "require": "./lib/commonjs/tab-bar/index.web.js"
1016
+ },
1017
+ "import": {
1018
+ "types": "./lib/typescript/module/tab-bar/index.d.ts",
1019
+ "default": "./lib/module/tab-bar/index.js"
1020
+ },
1021
+ "require": {
1022
+ "types": "./lib/typescript/commonjs/tab-bar/index.d.ts",
1023
+ "default": "./lib/commonjs/tab-bar/index.js"
1024
+ }
1025
+ },
1026
+ "./tab-bar/expo-router": {
1027
+ "react-native": "./src/tab-bar/expo-router/index.ts",
1028
+ "import": {
1029
+ "types": "./lib/typescript/module/tab-bar/expo-router/index.d.ts",
1030
+ "default": "./lib/module/tab-bar/expo-router/index.js"
1031
+ },
1032
+ "require": {
1033
+ "types": "./lib/typescript/commonjs/tab-bar/expo-router/index.d.ts",
1034
+ "default": "./lib/commonjs/tab-bar/expo-router/index.js"
1035
+ }
1036
+ },
1037
+ "./progressive-blur": {
1038
+ "react-native": "./src/progressive-blur/index.tsx",
1039
+ "browser": {
1040
+ "types": "./lib/typescript/module/progressive-blur/index.web.d.ts",
1041
+ "import": "./lib/module/progressive-blur/index.web.js",
1042
+ "require": "./lib/commonjs/progressive-blur/index.web.js"
1043
+ },
1044
+ "import": {
1045
+ "types": "./lib/typescript/module/progressive-blur/index.d.ts",
1046
+ "default": "./lib/module/progressive-blur/index.js"
1047
+ },
1048
+ "require": {
1049
+ "types": "./lib/typescript/commonjs/progressive-blur/index.d.ts",
1050
+ "default": "./lib/commonjs/progressive-blur/index.js"
1051
+ }
1052
+ },
1015
1053
  "./design-tokens/theme.css": "./src/design-tokens/theme.css",
1016
1054
  "./package.json": "./package.json"
1017
1055
  },
1018
1056
  "files": [
1019
1057
  "src",
1020
- "lib"
1058
+ "lib",
1059
+ "NOTICE"
1021
1060
  ],
1022
1061
  "keywords": [
1023
1062
  "react-native",
@@ -1088,8 +1127,8 @@
1088
1127
  "typescript": "tsc --noEmit",
1089
1128
  "pretypescript": "node scripts/generate-font-data.mjs",
1090
1129
  "clean": "rm -rf lib",
1091
- "prepack": "bun run clean && bunx bob build",
1092
- "prepare": "bob build || true",
1130
+ "prepack": "bun run clean && bun run build",
1131
+ "prepare": "bun run build || true",
1093
1132
  "release": "rm -rf lib && bun run build && release-it",
1094
1133
  "storybook": "storybook dev -p 6006 --no-open",
1095
1134
  "storybook:build": "storybook build -o storybook-static"
@@ -1121,9 +1160,11 @@
1121
1160
  "@vitejs/plugin-react": "^6.0.2",
1122
1161
  "expo-blur": "~56.0.3",
1123
1162
  "expo-font": "^56.0.5",
1163
+ "expo-glass-effect": "~56.0.4",
1124
1164
  "expo-haptics": "~56.0.3",
1125
1165
  "expo-image": "~56.0.11",
1126
1166
  "expo-router": "^56.0.0",
1167
+ "expo-symbols": "~56.0.6",
1127
1168
  "jest": "^30.3.0",
1128
1169
  "jest-environment-jsdom": "^30.4.1",
1129
1170
  "react": "19.2.0",
@@ -1131,14 +1172,14 @@
1131
1172
  "react-native": "0.83.2",
1132
1173
  "react-native-builder-bob": "^0.40.16",
1133
1174
  "react-native-gesture-handler": "^2.30.0",
1134
- "react-native-reanimated": "^4.2.2",
1175
+ "react-native-reanimated": "^4.5.0",
1135
1176
  "react-native-safe-area-context": "~5.6.0",
1177
+ "react-native-screens": "^4.25.2",
1136
1178
  "react-native-svg": "^15.15.3",
1137
1179
  "react-native-web": "^0.21.2",
1180
+ "react-native-worklets": "0.10.0",
1138
1181
  "react-test-renderer": "^19.2.0",
1139
1182
  "release-it": "^19.0.6",
1140
- "sonner": "^2.0.3",
1141
- "sonner-native": "^0.23.1",
1142
1183
  "storybook": "^10",
1143
1184
  "ts-jest": "^29.4.6",
1144
1185
  "typescript": "~5.9.2",
@@ -1148,18 +1189,19 @@
1148
1189
  "expo": "*",
1149
1190
  "expo-blur": "*",
1150
1191
  "expo-font": "*",
1192
+ "expo-glass-effect": ">=0.1.5",
1151
1193
  "expo-haptics": "*",
1152
1194
  "expo-image": "*",
1153
1195
  "expo-router": ">=3.0.0",
1196
+ "expo-symbols": ">=0.4.5",
1154
1197
  "react": ">=18.0.0",
1155
1198
  "react-dom": ">=18.0.0",
1156
1199
  "react-native": ">=0.73.0",
1157
- "react-native-gesture-handler": ">=2.0.0",
1158
- "react-native-reanimated": ">=3.0.0",
1200
+ "react-native-gesture-handler": ">=2.16.1",
1201
+ "react-native-reanimated": ">=3.13.0",
1159
1202
  "react-native-safe-area-context": ">=5.0.0",
1203
+ "react-native-screens": ">=3.16.0",
1160
1204
  "react-native-svg": ">=13.0.0",
1161
- "sonner": ">=2.0.0",
1162
- "sonner-native": ">=0.17.0",
1163
1205
  "nativewind": ">=5.0.0"
1164
1206
  },
1165
1207
  "peerDependenciesMeta": {
@@ -1169,22 +1211,19 @@
1169
1211
  "expo-font": {
1170
1212
  "optional": true
1171
1213
  },
1172
- "expo-haptics": {
1173
- "optional": true
1174
- },
1175
- "expo-router": {
1214
+ "expo-glass-effect": {
1176
1215
  "optional": true
1177
1216
  },
1178
- "react-dom": {
1217
+ "expo-haptics": {
1179
1218
  "optional": true
1180
1219
  },
1181
- "react-native-svg": {
1220
+ "expo-router": {
1182
1221
  "optional": true
1183
1222
  },
1184
- "sonner": {
1223
+ "expo-symbols": {
1185
1224
  "optional": true
1186
1225
  },
1187
- "sonner-native": {
1226
+ "react-dom": {
1188
1227
  "optional": true
1189
1228
  },
1190
1229
  "nativewind": {
@@ -1218,7 +1257,6 @@
1218
1257
  },
1219
1258
  "dependencies": {
1220
1259
  "@tanstack/react-virtual": "^3.14.3",
1221
- "nanoid": "^5.1.5",
1222
1260
  "react-native-css": "3.0.7",
1223
1261
  "react-remove-scroll-bar": "^2.3.8"
1224
1262
  },
@@ -0,0 +1,342 @@
1
+ import React from 'react';
2
+ import type { ReactTestInstance } from 'react-test-renderer';
3
+ import { fireEvent, render } from '@testing-library/react-native';
4
+
5
+ import { BloomThemeProvider } from '../theme/BloomThemeProvider';
6
+ import type { ThemeColors } from '../theme/types';
7
+ import { useTheme } from '../theme/use-theme';
8
+ import { TabBar, TabBarButton } from '../tab-bar';
9
+ import { TabBarGlyph as NativeTabBarGlyph } from '../tab-bar/glyph.native';
10
+ import { resolveTabBarTheme } from '../tab-bar/shared';
11
+ import { TabBarSurface as NativeTabBarSurface } from '../tab-bar/surface.native';
12
+ import type { TabBarItem, TabBarTheme } from '../tab-bar/types';
13
+
14
+ /**
15
+ * Behaviour tests for the floating tab bar.
16
+ *
17
+ * Three properties of the environment shape every assertion here:
18
+ *
19
+ * 1. Jest has no platform-extension resolution, so `../tab-bar` binds the
20
+ * NEUTRAL `surface.tsx` / `glyph.tsx`. The two `.native` variants are pulled
21
+ * in by their full path where they are asserted on directly — which is also
22
+ * what makes the `expo-glass-effect` / `expo-symbols` mocks load-bearing
23
+ * rather than decorative.
24
+ * 2. Labels render through `Animated.Text`, a plain host string under the
25
+ * reanimated mock, so testing-library's text queries cannot see them.
26
+ * `labelFor` walks the tree instead.
27
+ * 3. The reanimated mock's shared values are plain boxes: writing
28
+ * `slideIndex.value` does NOT re-render, and `useAnimatedStyle` runs during
29
+ * render. A mapper reading a shared value that an EFFECT wrote therefore
30
+ * reflects the write only on the NEXT render — hence `renderSettled`. The
31
+ * motion itself is verified in a real browser, not here.
32
+ */
33
+
34
+ /**
35
+ * Stand-in for a Bloom icon element: a host node tagged with the `fill` it was
36
+ * cloned with, so a test can read back the tint the bar injected through
37
+ * `applyIconColor`.
38
+ */
39
+ function BareIcon({ id, fill }: { id: string; fill?: string }) {
40
+ return React.createElement('bloom-test-icon', { testID: id, fill });
41
+ }
42
+
43
+ const ITEMS: TabBarItem[] = [
44
+ { name: 'home', label: 'Home', icon: <BareIcon id="home-icon" /> },
45
+ { name: 'search', label: 'Search', icon: <BareIcon id="search-icon" /> },
46
+ { name: 'you', label: 'You', icon: <BareIcon id="you-icon" /> },
47
+ ];
48
+
49
+ /** Captures the live `ThemeColors` so assertions compare against real tokens. */
50
+ function ThemeProbe({ onColors }: { onColors: (colors: ThemeColors) => void }) {
51
+ onColors(useTheme().colors);
52
+ return null;
53
+ }
54
+
55
+ function withTheme(ui: React.ReactElement) {
56
+ return (
57
+ <BloomThemeProvider mode="light" colorPreset="teal">
58
+ {ui}
59
+ </BloomThemeProvider>
60
+ );
61
+ }
62
+
63
+ function renderWithTheme(ui: React.ReactElement) {
64
+ return render(withTheme(ui));
65
+ }
66
+
67
+ /**
68
+ * Render, then re-render an equivalent tree so mappers see the shared-value
69
+ * writes the mount effects made. See note 3 in the file header.
70
+ *
71
+ * Takes a FACTORY, not an element: React bails out of re-rendering a
72
+ * referentially identical element, which would skip the second pass entirely
73
+ * and silently leave the assertion reading first-frame values.
74
+ */
75
+ function renderSettled(ui: () => React.ReactElement) {
76
+ const utils = renderWithTheme(ui());
77
+ utils.rerender(withTheme(ui()));
78
+ return utils;
79
+ }
80
+
81
+ /** The theme the bar resolves for `mode="light" colorPreset="teal"`. */
82
+ function readTheme(overrides?: Partial<TabBarTheme>): TabBarTheme {
83
+ let resolved: TabBarTheme | undefined;
84
+ renderWithTheme(
85
+ <ThemeProbe
86
+ onColors={(colors) => {
87
+ resolved = resolveTabBarTheme(colors, overrides);
88
+ }}
89
+ />,
90
+ );
91
+ if (!resolved) throw new Error('ThemeProbe never ran');
92
+ return resolved;
93
+ }
94
+
95
+ // Flatten a (possibly nested / conditional) RN style prop into one object.
96
+ function flattenStyle(style: unknown): Record<string, unknown> {
97
+ const out: Record<string, unknown> = {};
98
+ const visit = (s: unknown): void => {
99
+ if (Array.isArray(s)) s.forEach(visit);
100
+ else if (s && typeof s === 'object') Object.assign(out, s);
101
+ };
102
+ visit(style);
103
+ return out;
104
+ }
105
+
106
+ /**
107
+ * The host tag a node renders as, or `null` for a composite.
108
+ *
109
+ * `ReactTestInstance['type']` is typed as `ElementType`, whose string arm is the
110
+ * union of KNOWN intrinsic tags — so comparing it directly to a mock host name
111
+ * like `'Animated.Text'` is a TS2367 "no overlap" error. Widening to `string`
112
+ * behind this accessor is the honest fix: these really are host tags, they are
113
+ * just ones the RN/reanimated mocks invent.
114
+ */
115
+ function hostName(node: ReactTestInstance): string | null {
116
+ const { type } = node;
117
+ return typeof type === 'string' ? type : null;
118
+ }
119
+
120
+ /**
121
+ * Every tab trigger, in bar order.
122
+ *
123
+ * Restricted to HOST nodes: the tree carries both the composite `Pressable` and
124
+ * the host element it renders, and both hold the same props — counting them all
125
+ * would double every tab.
126
+ */
127
+ function triggers(root: ReactTestInstance): ReactTestInstance[] {
128
+ return root.findAll(
129
+ (node) => hostName(node) !== null && node.props?.accessibilityRole === 'tab',
130
+ );
131
+ }
132
+
133
+ /** The `Animated.Text` label node of the tab whose text is `label`. */
134
+ function labelFor(root: ReactTestInstance, label: string): ReactTestInstance {
135
+ const found = root.findAll(
136
+ (node) => hostName(node) === 'Animated.Text' && node.props?.children === label,
137
+ );
138
+ const first = found[0];
139
+ if (!first) throw new Error(`No tab label rendered with text "${label}"`);
140
+ return first;
141
+ }
142
+
143
+ /** Every host node rendered as `tag`. */
144
+ function hosts(root: ReactTestInstance, tag: string): ReactTestInstance[] {
145
+ return root.findAll((node) => hostName(node) === tag);
146
+ }
147
+
148
+ function selectedFlags(root: ReactTestInstance): boolean[] {
149
+ return triggers(root).map((node) => node.props.accessibilityState.selected);
150
+ }
151
+
152
+ function Bar({
153
+ activeIndex,
154
+ onIndexChange,
155
+ theme,
156
+ focusedIndex,
157
+ }: {
158
+ activeIndex?: number;
159
+ onIndexChange?: (index: number) => void;
160
+ theme?: Partial<TabBarTheme>;
161
+ /** When set, drives the FOCUS path (`isFocused`) instead of `activeIndex`. */
162
+ focusedIndex?: number;
163
+ }) {
164
+ return (
165
+ <TabBar activeIndex={activeIndex} onIndexChange={onIndexChange} theme={theme}>
166
+ {ITEMS.map((item, index) => (
167
+ <TabBarButton
168
+ key={item.name}
169
+ item={item}
170
+ index={index}
171
+ isFocused={focusedIndex === undefined ? undefined : focusedIndex === index}
172
+ />
173
+ ))}
174
+ </TabBar>
175
+ );
176
+ }
177
+
178
+ describe('TabBar', () => {
179
+ it('renders every item label', () => {
180
+ const { UNSAFE_root } = renderWithTheme(<Bar activeIndex={0} />);
181
+ for (const item of ITEMS) expect(labelFor(UNSAFE_root, item.label)).toBeTruthy();
182
+ });
183
+
184
+ it("renders each item's own icon node, on both crossfade layers", () => {
185
+ const { getAllByTestId } = renderWithTheme(<Bar activeIndex={0} />);
186
+ // The bar renders the glyph twice per tab: an inactive layer with the
187
+ // active layer crossfading on top.
188
+ for (const id of ['home-icon', 'search-icon', 'you-icon']) {
189
+ expect(getAllByTestId(id)).toHaveLength(2);
190
+ }
191
+ });
192
+
193
+ it('injects the layer tint as the icon fill, from theme tokens', () => {
194
+ const theme = readTheme();
195
+ const { getAllByTestId } = renderWithTheme(<Bar activeIndex={0} />);
196
+ const fills = getAllByTestId('home-icon').map((node) => node.props.fill);
197
+ expect(fills).toEqual(expect.arrayContaining([theme.inactiveTint, theme.activeTint]));
198
+ });
199
+
200
+ it('marks the tab at activeIndex as selected for accessibility', () => {
201
+ const { UNSAFE_root } = renderWithTheme(<Bar activeIndex={1} />);
202
+ expect(selectedFlags(UNSAFE_root)).toEqual([false, true, false]);
203
+ });
204
+
205
+ it('moves the selection when activeIndex changes', () => {
206
+ const { UNSAFE_root, rerender } = renderWithTheme(<Bar activeIndex={0} />);
207
+ rerender(withTheme(<Bar activeIndex={2} />));
208
+ expect(selectedFlags(UNSAFE_root)).toEqual([false, false, true]);
209
+ });
210
+
211
+ it('tints the label of the tab the highlight sits on', () => {
212
+ const theme = readTheme();
213
+ const { UNSAFE_root } = renderSettled(() => <Bar activeIndex={1} />);
214
+ expect(flattenStyle(labelFor(UNSAFE_root, 'Search').props.style).color).toBe(theme.activeTint);
215
+ expect(flattenStyle(labelFor(UNSAFE_root, 'Home').props.style).color).toBe(theme.inactiveTint);
216
+ });
217
+
218
+ it('calls onIndexChange with the pressed index', () => {
219
+ const onIndexChange = jest.fn();
220
+ const { UNSAFE_root } = renderWithTheme(<Bar activeIndex={0} onIndexChange={onIndexChange} />);
221
+ fireEvent.press(triggers(UNSAFE_root)[2] as ReactTestInstance);
222
+ expect(onIndexChange).toHaveBeenCalledTimes(1);
223
+ expect(onIndexChange).toHaveBeenCalledWith(2);
224
+ });
225
+
226
+ it('does not report the press itself on the focus-driven path', () => {
227
+ // With `isFocused` supplied the router trigger's own onPress navigates;
228
+ // reporting through the bar as well would navigate twice.
229
+ const onIndexChange = jest.fn();
230
+ const { UNSAFE_root } = renderWithTheme(
231
+ <Bar focusedIndex={0} onIndexChange={onIndexChange} />,
232
+ );
233
+ fireEvent.press(triggers(UNSAFE_root)[1] as ReactTestInstance);
234
+ expect(onIndexChange).not.toHaveBeenCalled();
235
+ });
236
+
237
+ it('lets isFocused override the bar activeIndex', () => {
238
+ const { UNSAFE_root } = renderWithTheme(
239
+ <TabBar activeIndex={0}>
240
+ {ITEMS.map((item, index) => (
241
+ <TabBarButton key={item.name} item={item} index={index} isFocused={index === 2} />
242
+ ))}
243
+ </TabBar>,
244
+ );
245
+ // Index 0 is the bar's activeIndex, but every button carries an explicit
246
+ // isFocused, so focus comes from the buttons alone.
247
+ expect(selectedFlags(UNSAFE_root)).toEqual([false, false, true]);
248
+ });
249
+
250
+ it('drives the highlight from isFocused when the bar is uncontrolled', () => {
251
+ const theme = readTheme();
252
+ // The router path: `RouterTabBarProps` omits `activeIndex` on purpose, so
253
+ // the focused BUTTON is the only writer of the highlight. This is what
254
+ // keeps the pill correct through deep links and back gestures.
255
+ const { UNSAFE_root } = renderSettled(() => <Bar focusedIndex={2} />);
256
+ // The label tint follows the sliding highlight, so it reports where the
257
+ // pill actually is.
258
+ expect(flattenStyle(labelFor(UNSAFE_root, 'You').props.style).color).toBe(theme.activeTint);
259
+ expect(flattenStyle(labelFor(UNSAFE_root, 'Home').props.style).color).toBe(theme.inactiveTint);
260
+ });
261
+
262
+ describe('theming', () => {
263
+ it('resolves its defaults from Bloom tokens, never a hardcoded palette', () => {
264
+ const theme = readTheme();
265
+ // Upstream shipped a fixed dark palette; every role must instead come
266
+ // from the active preset, which resolves to Bloom's `rgb(...)` tokens.
267
+ for (const [role, value] of Object.entries(theme)) {
268
+ expect([role, value]).toEqual([role, expect.stringMatching(/^rgba?\(/)]);
269
+ }
270
+ expect(theme.activeTint).not.toBe('#FFFFFF');
271
+ expect(theme.activeTint).not.toBe(theme.inactiveTint);
272
+ });
273
+
274
+ it('paints the highlight with the resolved highlight token', () => {
275
+ const theme = readTheme();
276
+ const { UNSAFE_root } = renderWithTheme(<Bar activeIndex={0} />);
277
+ const painted = UNSAFE_root.findAll(
278
+ (node) => flattenStyle(node.props?.style).backgroundColor === theme.highlight,
279
+ );
280
+ expect(painted.length).toBeGreaterThan(0);
281
+ });
282
+
283
+ it('applies a partial theme override without dropping the other roles', () => {
284
+ const defaults = readTheme();
285
+ const overridden = readTheme({ highlight: 'rgb(1 2 3)' });
286
+ expect(overridden.highlight).toBe('rgb(1 2 3)');
287
+ expect(overridden.activeTint).toBe(defaults.activeTint);
288
+ expect(overridden.glassTint).toBe(defaults.glassTint);
289
+ });
290
+
291
+ it('never lets an explicit undefined in a partial punch a hole', () => {
292
+ const defaults = readTheme();
293
+ expect(readTheme({ activeTint: undefined }).activeTint).toBe(defaults.activeTint);
294
+ });
295
+
296
+ it('paints the bar with an overridden highlight', () => {
297
+ const { UNSAFE_root } = renderWithTheme(
298
+ <Bar activeIndex={0} theme={{ highlight: 'rgb(9 9 9)' }} />,
299
+ );
300
+ const painted = UNSAFE_root.findAll(
301
+ (node) => flattenStyle(node.props?.style).backgroundColor === 'rgb(9 9 9)',
302
+ );
303
+ expect(painted.length).toBeGreaterThan(0);
304
+ });
305
+ });
306
+
307
+ describe('native platform variants', () => {
308
+ it('falls back to the solid theme fill when liquid glass is unavailable', () => {
309
+ // The `expo-glass-effect` mock reports `isLiquidGlassAvailable() === false`
310
+ // (see the note in that file), so this is the branch every Android and
311
+ // pre-iOS-26 device takes.
312
+ const theme = readTheme();
313
+ const { UNSAFE_root } = renderWithTheme(
314
+ <NativeTabBarSurface theme={theme} style={{ borderRadius: 29 }} />,
315
+ );
316
+ expect(hosts(UNSAFE_root, 'GlassView')).toHaveLength(0);
317
+ const surface = hosts(UNSAFE_root, 'Animated.View')[0];
318
+ expect(flattenStyle(surface?.props.style).backgroundColor).toBe(theme.solidFallback);
319
+ });
320
+
321
+ it('renders an SF Symbol on iOS when the item carries one', () => {
322
+ const theme = readTheme();
323
+ const item: TabBarItem = { ...(ITEMS[0] as TabBarItem), sfSymbol: 'house.fill' };
324
+ const { UNSAFE_root } = renderWithTheme(
325
+ <NativeTabBarGlyph item={item} tint={theme.activeTint} size={21} />,
326
+ );
327
+ const symbol = hosts(UNSAFE_root, 'SymbolView')[0];
328
+ expect(symbol?.props.name).toBe('house.fill');
329
+ expect(symbol?.props.tintColor).toBe(theme.activeTint);
330
+ expect(symbol?.props.size).toBe(21);
331
+ });
332
+
333
+ it('falls back to the item icon when no SF Symbol is given', () => {
334
+ const theme = readTheme();
335
+ const { queryByTestId, UNSAFE_root } = renderWithTheme(
336
+ <NativeTabBarGlyph item={ITEMS[0] as TabBarItem} tint={theme.activeTint} size={21} />,
337
+ );
338
+ expect(hosts(UNSAFE_root, 'SymbolView')).toHaveLength(0);
339
+ expect(queryByTestId('home-icon')).toBeTruthy();
340
+ });
341
+ });
342
+ });
@@ -0,0 +1,130 @@
1
+ import { readdirSync, readFileSync, statSync } from 'node:fs';
2
+ import { join, relative } from 'node:path';
3
+
4
+ /**
5
+ * Every reanimated mapper in the tab bar must pass a NON-EMPTY dependency array.
6
+ *
7
+ * On web WITHOUT the react-native-worklets babel plugin — the production reality
8
+ * for every Oxy RN-Web app — reanimated cannot auto-detect which shared values a
9
+ * worklet reads, so it drives the mapper off its deps array instead. A missing or
10
+ * empty array means the mapper runs ONCE and freezes at the first frame: the
11
+ * shared values keep animating underneath, the DOM never updates. For this
12
+ * component that means a bar that never minimizes, a highlight that never moves
13
+ * and a scroll handler bound to the first render's state — with no error
14
+ * anywhere. Native (plugin present) auto-tracks and ignores the extra deps, so
15
+ * listing them is correct on both platforms.
16
+ *
17
+ * This is deliberately STRICTER than the repo-wide `animated-style-deps` guard,
18
+ * which only checks that the values a mapper reads appear in the deps it
19
+ * declares. Here every mapper must carry a real deps array whether or not the
20
+ * regex can see a `.value` read inside it, and `useAnimatedScrollHandler` — which
21
+ * the repo-wide guard does not scan at all — is included, because
22
+ * `useMinimizeOnScroll` is the single entry point through which every screen
23
+ * drives the bar.
24
+ *
25
+ * Jest cannot catch this class at all: the reanimated mock resolves mappers
26
+ * synchronously, so a frozen mapper and a working one render identically. Source
27
+ * analysis is the only automatable check; the real behaviour is verified in a
28
+ * foregrounded browser tab.
29
+ */
30
+
31
+ const SRC = join(__dirname, '..');
32
+ const ROOTS = ['tab-bar', 'progressive-blur'] as const;
33
+ const MAPPERS = [
34
+ 'useAnimatedStyle',
35
+ 'useAnimatedScrollHandler',
36
+ 'useDerivedValue',
37
+ 'useAnimatedProps',
38
+ ] as const;
39
+
40
+ /**
41
+ * Floors for the self-check, not exact counts — a new mapper or module must not
42
+ * fail this suite, but a walk that silently stops finding things must.
43
+ */
44
+ const MIN_FILES = 16;
45
+ const MIN_MAPPERS = 7;
46
+
47
+ type Offender = { location: string; mapper: string; problem: string };
48
+
49
+ /** Comments legitimately discuss mappers and show them in examples. */
50
+ function stripComments(source: string): string {
51
+ return source
52
+ .replace(/\/\*[\s\S]*?\*\//g, (block) => '\n'.repeat((block.match(/\n/g) ?? []).length))
53
+ .replace(/^[ \t]*\/\/.*$/gm, '');
54
+ }
55
+
56
+ function sourceFiles(dir: string): string[] {
57
+ return readdirSync(dir).flatMap((entry) => {
58
+ const full = join(dir, entry);
59
+ if (statSync(full).isDirectory()) {
60
+ return entry === '__tests__' ? [] : sourceFiles(full);
61
+ }
62
+ return /\.tsx?$/.test(entry) ? [full] : [];
63
+ });
64
+ }
65
+
66
+ /** Text between the parens of the call starting at `start`, paren-balanced. */
67
+ function callText(source: string, start: number): string {
68
+ const open = source.indexOf('(', start);
69
+ let depth = 0;
70
+ for (let i = open; i < source.length; i++) {
71
+ if (source[i] === '(') depth += 1;
72
+ else if (source[i] === ')') {
73
+ depth -= 1;
74
+ if (depth === 0) return source.slice(open + 1, i);
75
+ }
76
+ }
77
+ return source.slice(open + 1);
78
+ }
79
+
80
+ function analyse(): { offenders: Offender[]; files: number; calls: number } {
81
+ const offenders: Offender[] = [];
82
+ const scanned = ROOTS.flatMap((root) => sourceFiles(join(SRC, root)));
83
+ let calls = 0;
84
+
85
+ for (const file of scanned) {
86
+ const source = stripComments(readFileSync(file, 'utf8'));
87
+
88
+ for (const mapper of MAPPERS) {
89
+ // `\b` before the name so `useAnimatedStyleX` can never match.
90
+ for (const call of source.matchAll(new RegExp(`\\b${mapper}\\s*\\(`, 'g'))) {
91
+ if (call.index === undefined) continue;
92
+ calls += 1;
93
+
94
+ const text = callText(source, call.index);
95
+ const line = source.slice(0, call.index).split('\n').length;
96
+ const location = `${relative(SRC, file)}:${line}`;
97
+
98
+ // Trailing comma after the deps array is idiomatic and must parse.
99
+ const deps = [...text.matchAll(/,\s*(\[[\s\S]*?\])\s*,?\s*$/g)].pop();
100
+ if (!deps) {
101
+ offenders.push({ location, mapper, problem: 'no deps array' });
102
+ continue;
103
+ }
104
+ if ((deps[1] ?? '').replace(/\s/g, '') === '[]') {
105
+ offenders.push({ location, mapper, problem: 'empty deps array' });
106
+ }
107
+ }
108
+ }
109
+ }
110
+
111
+ return { offenders, files: scanned.length, calls };
112
+ }
113
+
114
+ const { offenders, files, calls } = analyse();
115
+
116
+ describe('tab-bar reanimated mapper dependency arrays', () => {
117
+ it('walked a plausible number of source files (guards against a broken walk)', () => {
118
+ expect(files).toBeGreaterThanOrEqual(MIN_FILES);
119
+ });
120
+
121
+ it('found a plausible number of mapper call sites (guards against a vacuous pass)', () => {
122
+ // Without this, a broken regex would make the real assertion below pass by
123
+ // finding nothing at all.
124
+ expect(calls).toBeGreaterThanOrEqual(MIN_MAPPERS);
125
+ });
126
+
127
+ it('has no mapper with a missing or empty deps array', () => {
128
+ expect(offenders.map((o) => `${o.location} ${o.mapper} — ${o.problem}`)).toEqual([]);
129
+ });
130
+ });