@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
@@ -0,0 +1,197 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+
4
+ /**
5
+ * Structural guard for the tab bar's platform split.
6
+ *
7
+ * `@oxyhq/bloom/tab-bar` has to resolve cleanly in four places at once: Metro on
8
+ * iOS/Android (platform extensions), a web bundler (the `browser` export
9
+ * condition), a non-Metro bundler reading the published `lib/`, and a consumer's
10
+ * `tsc` (which follows the `"react-native"` source condition). Three packages
11
+ * break that the moment they appear outside a `.native` file:
12
+ * `expo-glass-effect` and `expo-symbols` are native-only, and `expo-router` /
13
+ * `react-native-screens` belong solely to the opt-in
14
+ * `@oxyhq/bloom/tab-bar/expo-router` subpath so the core bar stays usable in an
15
+ * app with no router at all.
16
+ *
17
+ * None of that is observable from a jest render — a missing `.web` retarget or a
18
+ * leaked native import fails at a consumer's BUILD, in a repo that isn't this
19
+ * one. Hence source/contract assertions.
20
+ *
21
+ * Every assertion below matches on real import/export/require STATEMENTS, never
22
+ * on bare substrings: the doc comments in these files name all four packages on
23
+ * purpose (explaining why they are absent), so `includes('expo-symbols')` would
24
+ * report a failure that is actually the documentation doing its job.
25
+ */
26
+
27
+ const SRC = join(__dirname, '..');
28
+ const REPO_ROOT = join(SRC, '..');
29
+
30
+ const read = (rel: string) => readFileSync(join(SRC, rel), 'utf8');
31
+
32
+ /** Packages that must never be reached from a neutral or web module. */
33
+ const PLATFORM_ONLY = [
34
+ 'expo-glass-effect',
35
+ 'expo-symbols',
36
+ 'expo-router',
37
+ 'react-native-screens',
38
+ ] as const;
39
+
40
+ /**
41
+ * Files resolved by a web bundler, a non-Metro bundler, or a consumer's `tsc`.
42
+ * `expo-router/index.ts` and its siblings are deliberately absent — that subpath
43
+ * is where the router packages are allowed to live.
44
+ */
45
+ const NEUTRAL_AND_WEB_FILES = [
46
+ 'tab-bar/index.ts',
47
+ 'tab-bar/index.web.tsx',
48
+ 'tab-bar/types.ts',
49
+ 'tab-bar/shared.ts',
50
+ 'tab-bar/TabBarBase.tsx',
51
+ 'tab-bar/minimize-context.tsx',
52
+ 'tab-bar/surface.tsx',
53
+ 'tab-bar/surface.web.tsx',
54
+ 'tab-bar/glyph.tsx',
55
+ 'progressive-blur/index.web.tsx',
56
+ 'progressive-blur/shared.ts',
57
+ 'progressive-blur/types.ts',
58
+ ] as const;
59
+
60
+ /**
61
+ * Blank out comments so a doc comment discussing a package is not mistaken for
62
+ * an import of it. Line comments are matched only when they START the line, so
63
+ * a `//` inside a string literal (a URL) survives untouched.
64
+ */
65
+ function stripComments(source: string): string {
66
+ return source
67
+ .replace(/\/\*[\s\S]*?\*\//g, '')
68
+ .replace(/^[ \t]*\/\/.*$/gm, '');
69
+ }
70
+
71
+ /** Every module specifier the file actually imports, re-exports or requires. */
72
+ function moduleSpecifiers(source: string): string[] {
73
+ const code = stripComments(source);
74
+ const patterns = [
75
+ /\bfrom\s*['"]([^'"]+)['"]/g, // import … from 'x' / export … from 'x'
76
+ /\bimport\s*['"]([^'"]+)['"]/g, // bare side-effect import 'x'
77
+ /\brequire\(\s*['"]([^'"]+)['"]\s*\)/g,
78
+ /\bimport\(\s*['"]([^'"]+)['"]\s*\)/g,
79
+ ];
80
+ const found = new Set<string>();
81
+ for (const pattern of patterns) {
82
+ for (const match of code.matchAll(pattern)) {
83
+ if (match[1]) found.add(match[1]);
84
+ }
85
+ }
86
+ return [...found];
87
+ }
88
+
89
+ /** True when `specifier` resolves to `pkg` (bare or a subpath of it). */
90
+ function isFrom(specifier: string, pkg: string): boolean {
91
+ return specifier === pkg || specifier.startsWith(`${pkg}/`);
92
+ }
93
+
94
+ describe('tab-bar platform split', () => {
95
+ it('the extractor sees real imports and ignores commented-out ones', () => {
96
+ // Self-check: if `moduleSpecifiers` breaks, every assertion below would
97
+ // pass vacuously by finding nothing.
98
+ const probe = [
99
+ "/* a doc comment naming expo-symbols and expo-router */",
100
+ "// import { Nope } from 'react-native-screens';",
101
+ "import { A } from 'react-native';",
102
+ "export type { B } from './types';",
103
+ "const c = require('expo-glass-effect');",
104
+ ].join('\n');
105
+ expect(moduleSpecifiers(probe).sort()).toEqual([
106
+ './types',
107
+ 'expo-glass-effect',
108
+ 'react-native',
109
+ ]);
110
+ });
111
+
112
+ it.each(NEUTRAL_AND_WEB_FILES)('%s imports no native-only or router package', (file) => {
113
+ const specifiers = moduleSpecifiers(read(file));
114
+ const leaked = specifiers.filter((s) => PLATFORM_ONLY.some((pkg) => isFrom(s, pkg)));
115
+ expect(leaked).toEqual([]);
116
+ });
117
+
118
+ it('the web progressive blur drops expo-blur for one masked backdrop-filter', () => {
119
+ // Ten stacked BlurViews would be ten composited backdrop passes per frame.
120
+ expect(moduleSpecifiers(read('progressive-blur/index.web.tsx'))).not.toContain('expo-blur');
121
+ expect(moduleSpecifiers(read('progressive-blur/index.tsx'))).toContain('expo-blur');
122
+ });
123
+
124
+ it('the native surface and glyph are the ONLY holders of the native packages', () => {
125
+ // The guard above only proves absence; this proves the split is real rather
126
+ // than the feature having quietly lost its native path.
127
+ expect(moduleSpecifiers(read('tab-bar/surface.native.tsx'))).toContain('expo-glass-effect');
128
+ expect(moduleSpecifiers(read('tab-bar/glyph.native.tsx'))).toContain('expo-symbols');
129
+ });
130
+
131
+ it('the router packages live only under tab-bar/expo-router', () => {
132
+ const router = moduleSpecifiers(read('tab-bar/expo-router/RouterTabBar.tsx'));
133
+ expect(router.some((s) => isFrom(s, 'expo-router'))).toBe(true);
134
+ const screen = moduleSpecifiers(read('tab-bar/expo-router/fading-tab-screen.tsx'));
135
+ expect(screen).toContain('react-native-screens');
136
+ });
137
+
138
+ it('the default entry imports the platform pieces BY BARE NAME (Metro picks .native)', () => {
139
+ const specifiers = moduleSpecifiers(read('tab-bar/index.ts'));
140
+ expect(specifiers).toContain('./surface');
141
+ expect(specifiers).toContain('./glyph');
142
+ expect(specifiers).toContain('../progressive-blur');
143
+ // A `.web` path here would pin every platform to the web fork.
144
+ expect(specifiers).not.toContain('./surface.web');
145
+ });
146
+
147
+ it('the web entry imports the web pieces by their FULL .web name', () => {
148
+ // Inside the published `lib/` every file is plain `.js`, and no web bundler
149
+ // resolves a bare `./surface` to the `.web` sibling — only Metro does.
150
+ const specifiers = moduleSpecifiers(read('tab-bar/index.web.tsx'));
151
+ expect(specifiers).toContain('./surface.web');
152
+ expect(specifiers).toContain('../progressive-blur/index.web');
153
+ expect(specifiers).not.toContain('./surface');
154
+ // `./glyph` has no web fork: the neutral file already renders `item.icon`,
155
+ // which is the correct web behaviour.
156
+ expect(specifiers).toContain('./glyph');
157
+ });
158
+ });
159
+
160
+ describe('tab-bar published surface', () => {
161
+ const pkg = JSON.parse(readFileSync(join(REPO_ROOT, 'package.json'), 'utf8')) as {
162
+ exports: Record<string, { browser?: { import?: string; require?: string } }>;
163
+ };
164
+
165
+ it('exports ./tab-bar with a browser condition → index.web.js', () => {
166
+ const entry = pkg.exports['./tab-bar'];
167
+ expect(entry).toBeDefined();
168
+ expect(entry?.browser?.import).toBe('./lib/module/tab-bar/index.web.js');
169
+ expect(entry?.browser?.require).toBe('./lib/commonjs/tab-bar/index.web.js');
170
+ });
171
+
172
+ it('exports ./progressive-blur with a browser condition → index.web.js', () => {
173
+ expect(pkg.exports['./progressive-blur']?.browser?.import).toBe(
174
+ './lib/module/progressive-blur/index.web.js',
175
+ );
176
+ });
177
+
178
+ it('exports ./tab-bar/expo-router with NO browser condition', () => {
179
+ // The router adapter is universal — it only re-binds `TabBar`/`TabBarButton`,
180
+ // whose own entry already resolves per platform. There is no `.web` sibling,
181
+ // so a browser condition would point at a file bob never emits.
182
+ const entry = pkg.exports['./tab-bar/expo-router'];
183
+ expect(entry).toBeDefined();
184
+ expect(entry?.browser).toBeUndefined();
185
+ });
186
+
187
+ it('the generator lists exactly the right subpaths as web-forked', () => {
188
+ const gen = readFileSync(join(REPO_ROOT, 'scripts/generate-platform-exports.mjs'), 'utf8');
189
+ const block = /const WEB_FORKED_SUBPATHS = new Set\(\[([\s\S]*?)\]\);/.exec(gen)?.[1];
190
+ expect(block).toBeDefined();
191
+ const listed = [...(block ?? '').matchAll(/^\s*'([^']+)',/gm)].map((m) => m[1]);
192
+ expect(listed).toContain('./tab-bar');
193
+ expect(listed).toContain('./progressive-blur');
194
+ // `assertWebSourceExists()` throws for this one — it has no `.web` sibling.
195
+ expect(listed).not.toContain('./tab-bar/expo-router');
196
+ });
197
+ });
@@ -0,0 +1,192 @@
1
+ import React from 'react';
2
+ import { Text } from 'react-native';
3
+ import { fireEvent, render } from '@testing-library/react-native';
4
+
5
+ import { BloomThemeProvider } from '../theme/BloomThemeProvider';
6
+ import { ToastContent } from '../toast/ToastContent';
7
+ import type { ToastVariant } from '../toast/types';
8
+
9
+ const renderContent = (
10
+ props: Partial<React.ComponentProps<typeof ToastContent>> = {},
11
+ ) => {
12
+ const onDismiss = jest.fn();
13
+ const utils = render(
14
+ <BloomThemeProvider mode="light" colorPreset="teal">
15
+ <ToastContent
16
+ id={1}
17
+ title="Saved"
18
+ unstyled={false}
19
+ icons={{}}
20
+ onDismiss={onDismiss}
21
+ {...props}
22
+ />
23
+ </BloomThemeProvider>,
24
+ );
25
+ return { ...utils, onDismiss };
26
+ };
27
+
28
+ /**
29
+ * `ReactTestInstance['type']` is `ElementType`, whose string arm is
30
+ * `keyof JSX.IntrinsicElements` — so comparing it to a React Native host name
31
+ * ('Pressable', 'Svg', …) is a type error. Normalise to a plain string instead of
32
+ * asserting the type away.
33
+ */
34
+ const hostName = (node: { type: unknown }): string =>
35
+ typeof node.type === 'string' ? node.type : '';
36
+
37
+ /**
38
+ * `*ByRole` does not resolve through this repo's `react-native` mock (it renders
39
+ * primitives as bare host elements), so button assertions go by component type.
40
+ */
41
+ const pressablesOf = ({ UNSAFE_root }: ReturnType<typeof renderContent>) =>
42
+ UNSAFE_root.findAll((node) => hostName(node) === 'Pressable');
43
+
44
+ /** Bloom icons render as `Svg` hosts. */
45
+ const iconsOf = ({ UNSAFE_root }: ReturnType<typeof renderContent>) =>
46
+ UNSAFE_root.findAll((node) => hostName(node) === 'Svg');
47
+
48
+ const spinnersOf = ({ UNSAFE_root }: ReturnType<typeof renderContent>) =>
49
+ UNSAFE_root.findAll((node) => hostName(node) === 'ActivityIndicator');
50
+
51
+ describe('ToastContent', () => {
52
+ it('renders the title', () => {
53
+ const { getByText } = renderContent();
54
+ expect(getByText('Saved')).toBeTruthy();
55
+ });
56
+
57
+ it('renders a description only when one is given', () => {
58
+ expect(renderContent().queryByText('Details')).toBeNull();
59
+ expect(
60
+ renderContent({ description: 'Details' }).getByText('Details'),
61
+ ).toBeTruthy();
62
+ });
63
+
64
+ it('renders an action button and calls onClick', () => {
65
+ const onClick = jest.fn();
66
+ const { getByText } = renderContent({
67
+ action: { label: 'Undo', onClick },
68
+ });
69
+
70
+ fireEvent.press(getByText('Undo'));
71
+ expect(onClick).toHaveBeenCalledTimes(1);
72
+ });
73
+
74
+ it('renders an action supplied as a node instead of a label/onClick pair', () => {
75
+ const { getByText } = renderContent({
76
+ action: <Text>Custom action</Text>,
77
+ });
78
+ expect(getByText('Custom action')).toBeTruthy();
79
+ });
80
+
81
+ it('dismisses after running the cancel handler', () => {
82
+ const onClick = jest.fn();
83
+ const { getByText, onDismiss } = renderContent({
84
+ cancel: { label: 'Dismiss', onClick },
85
+ });
86
+
87
+ fireEvent.press(getByText('Dismiss'));
88
+ expect(onClick).toHaveBeenCalledTimes(1);
89
+ expect(onDismiss).toHaveBeenCalledWith(1);
90
+ });
91
+
92
+ it('shows no button row when there is neither action nor cancel', () => {
93
+ expect(pressablesOf(renderContent())).toHaveLength(0);
94
+ });
95
+
96
+ it('renders the close button only when asked, and it dismisses', () => {
97
+ expect(pressablesOf(renderContent({ dismissible: true }))).toHaveLength(0);
98
+
99
+ const rendered = renderContent({ dismissible: true, closeButton: true });
100
+ const [closeButton] = pressablesOf(rendered);
101
+ expect(closeButton).toBeDefined();
102
+ if (closeButton) {
103
+ fireEvent.press(closeButton);
104
+ }
105
+ expect(rendered.onDismiss).toHaveBeenCalledWith(1);
106
+ });
107
+
108
+ it('never renders a close button on a non-dismissible toast', () => {
109
+ expect(
110
+ pressablesOf(renderContent({ dismissible: false, closeButton: true })),
111
+ ).toHaveLength(0);
112
+ });
113
+
114
+ it('prefers a caller-supplied close node over the default button', () => {
115
+ const { getByText } = renderContent({
116
+ dismissible: true,
117
+ closeButton: true,
118
+ close: <Text>Bye</Text>,
119
+ });
120
+ expect(getByText('Bye')).toBeTruthy();
121
+ });
122
+
123
+ it('renders a variant icon, and none for a variant-less toast', () => {
124
+ // A neutral toast has no leading icon at all.
125
+ expect(iconsOf(renderContent({ variant: 'success' })).length).toBeGreaterThan(
126
+ iconsOf(renderContent()).length,
127
+ );
128
+ });
129
+
130
+ it.each<ToastVariant>(['success', 'error', 'warning', 'info'])(
131
+ 'renders an icon for the %s variant',
132
+ (variant) => {
133
+ expect(iconsOf(renderContent({ variant })).length).toBeGreaterThan(0);
134
+ },
135
+ );
136
+
137
+ it('uses a spinner instead of an icon while a promise is pending', () => {
138
+ const rendered = renderContent({
139
+ promiseOptions: {
140
+ promise: Promise.resolve('done'),
141
+ loading: 'Saving…',
142
+ error: 'Failed',
143
+ },
144
+ });
145
+ expect(spinnersOf(rendered)).toHaveLength(1);
146
+ expect(iconsOf(rendered)).toHaveLength(0);
147
+ });
148
+
149
+ it('lets the outlet override the loading indicator', () => {
150
+ const { getByText } = renderContent({
151
+ variant: 'loading',
152
+ icons: { loading: <Text>spinning</Text> },
153
+ });
154
+ expect(getByText('spinning')).toBeTruthy();
155
+ });
156
+
157
+ it('lets the outlet override a variant icon', () => {
158
+ const { getByText } = renderContent({
159
+ variant: 'success',
160
+ icons: { success: <Text>yay</Text> },
161
+ });
162
+ expect(getByText('yay')).toBeTruthy();
163
+ });
164
+
165
+ it('prefers a per-toast icon over the variant icon', () => {
166
+ const { getByText } = renderContent({
167
+ variant: 'success',
168
+ icon: <Text>mine</Text>,
169
+ icons: { success: <Text>yay</Text> },
170
+ });
171
+ expect(getByText('mine')).toBeTruthy();
172
+ });
173
+
174
+ it('applies caller style overrides to the title', () => {
175
+ const { getByText } = renderContent({
176
+ styles: { title: { fontSize: 99 } },
177
+ });
178
+ expect(getByText('Saved').props.style).toEqual(
179
+ expect.arrayContaining([{ fontSize: 99 }]),
180
+ );
181
+ });
182
+
183
+ it('drops its own surface and text styling when unstyled', () => {
184
+ const { getByText } = renderContent({ unstyled: true });
185
+ // Only the (absent) override slot remains, so nothing carries a colour.
186
+ expect(getByText('Saved').props.style).toEqual([
187
+ undefined,
188
+ undefined,
189
+ undefined,
190
+ ]);
191
+ });
192
+ });
@@ -0,0 +1,155 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+
4
+ /**
5
+ * Source/contract guards for the toast host split, mirroring
6
+ * `BottomSheetWebFork.test.ts`.
7
+ *
8
+ * The toast engine is ONE universal implementation; its only platform split is
9
+ * the host. Several of the properties below cannot be reproduced in jest (the
10
+ * real paint, the portal ancestry, Metro's `.native` resolution), so they are
11
+ * asserted against the source and the generated packaging instead, and verified
12
+ * for real in a browser and on a device.
13
+ */
14
+
15
+ const SRC = join(__dirname, '..');
16
+ const REPO_ROOT = join(SRC, '..');
17
+
18
+ const read = (rel: string) => readFileSync(join(SRC, rel), 'utf8');
19
+
20
+ /**
21
+ * Source with comments removed. These files deliberately DOCUMENT the patterns
22
+ * they must not contain (`ToastHost.native.tsx` shows a consumer how to inject
23
+ * `FullWindowOverlay`; `Positioner.tsx` explains why it holds no `position:
24
+ * 'fixed'`), so every negative assertion runs against code only.
25
+ */
26
+ const code = (rel: string) =>
27
+ read(rel)
28
+ .replace(/\/\*[\s\S]*?\*\//g, '')
29
+ .replace(/^\s*\/\/.*$/gm, '');
30
+
31
+ describe('ToastHost platform split', () => {
32
+ it('web/default host portals into the shared bloom portal root', () => {
33
+ const host = read('toast/ToastHost.tsx');
34
+ expect(host).toMatch(/from '\.\.\/portal\/index\.web'/);
35
+ expect(host).toMatch(/<Portal>/);
36
+ });
37
+
38
+ it('web/default host provides its own GestureHandlerRootView (W8)', () => {
39
+ const host = read('toast/ToastHost.tsx');
40
+ // Portaled content sits outside the app-root GHRV, so swipe-to-dismiss
41
+ // would never receive touches without this.
42
+ expect(host).toMatch(
43
+ /import \{ GestureHandlerRootView \} from 'react-native-gesture-handler'/,
44
+ );
45
+ });
46
+
47
+ it('web/default host anchors to the viewport through the shared style module (W7)', () => {
48
+ const host = code('toast/ToastHost.tsx');
49
+ expect(host).toMatch(/position: WEB_POSITION_FIXED/);
50
+ expect(host).toMatch(/from '\.\.\/styles\/web-view-style'/);
51
+ // The one-off inline cast this replaces must never come back.
52
+ expect(host).not.toMatch(/'fixed' as/);
53
+ });
54
+
55
+ it('web/default host layers toasts at Z_INDEX.toast', () => {
56
+ const host = read('toast/ToastHost.tsx');
57
+ expect(host).toMatch(/zIndex: Z_INDEX\.toast/);
58
+ });
59
+
60
+ it('native host imports neither react-native-screens nor the portal (D6)', () => {
61
+ const native = code('toast/ToastHost.native.tsx');
62
+ expect(native).not.toMatch(/from 'react-native-screens'/);
63
+ expect(native).not.toMatch(/from '\.\.\/portal/);
64
+ expect(native).toMatch(/ToasterOverlayWrapper/);
65
+ // The doc comment still has to tell consumers how to inject it themselves.
66
+ expect(read('toast/ToastHost.native.tsx')).toMatch(/FullWindowOverlay/);
67
+ });
68
+
69
+ it('the shared style module owns the only fixed-position assertion', () => {
70
+ const styleModule = read('styles/web-view-style.ts');
71
+ expect(styleModule).toMatch(
72
+ /export const WEB_POSITION_FIXED = 'fixed' as ViewStyle\['position'\]/,
73
+ );
74
+ // Exactly one cast in the module, and nothing else exported alongside it.
75
+ // (Counted against code — the doc comment discusses casts in prose.)
76
+ expect(code('styles/web-view-style.ts').match(/ as /g)).toHaveLength(1);
77
+ expect(styleModule.match(/^export /gm)).toHaveLength(1);
78
+ });
79
+
80
+ it('no engine file other than the host reaches for a platform overlay', () => {
81
+ for (const file of [
82
+ 'toast/Toaster.tsx',
83
+ 'toast/Positioner.tsx',
84
+ 'toast/ToastRow.tsx',
85
+ ]) {
86
+ const source = code(file);
87
+ expect(source).not.toMatch(/from 'react-native-screens'/);
88
+ // Doc comments explain why `fixed` lives in the host; assert no file here
89
+ // actually POSITIONS anything fixed.
90
+ expect(source).not.toMatch(/position:\s*'fixed'/);
91
+ expect(source).not.toMatch(/webPosition\(/);
92
+ }
93
+ });
94
+
95
+ it('never returns an animation from a mapper (reanimated web failure mode A)', () => {
96
+ // `useDerivedValue(() => withTiming(...))` and a `withTiming` returned from
97
+ // inside `useAnimatedStyle` do not tick on web: the value jumps to a static
98
+ // frame. Every animation must be ASSIGNED from JS instead — the row's shared
99
+ // values come from `useAnimatedTarget`, and its mappers only read them.
100
+ for (const file of [
101
+ 'toast/ToastRow.tsx',
102
+ 'toast/use-toast-position.ts',
103
+ 'toast/ToastSwipeHandler.tsx',
104
+ ]) {
105
+ const source = code(file);
106
+ expect(source).not.toMatch(/useDerivedValue/);
107
+ expect(source).not.toMatch(/return withTiming/);
108
+ }
109
+
110
+ const driver = code('toast/use-animated-target.ts');
111
+ expect(driver).toMatch(/value\.value = withTiming\(/);
112
+ expect(driver).not.toMatch(/useDerivedValue/);
113
+ });
114
+
115
+ it('Positioner passes pointerEvents through style, not as a prop', () => {
116
+ const positioner = code('toast/Positioner.tsx');
117
+ expect(positioner).toMatch(/pointerEvents:/);
118
+ expect(positioner).not.toMatch(/pointerEvents=\{/);
119
+ });
120
+
121
+ it('package.json exports ./toast WITHOUT a browser condition', () => {
122
+ const pkg = JSON.parse(readFileSync(join(REPO_ROOT, 'package.json'), 'utf8')) as {
123
+ exports: Record<string, { browser?: unknown; import?: { default?: string } }>;
124
+ };
125
+ const entry = pkg.exports['./toast'];
126
+ expect(entry).toBeDefined();
127
+ // A browser condition would emit lib/module/toast/index.web.js, and any
128
+ // bundler with `.web.js` in resolve.extensions would resolve `./toast` to it.
129
+ expect(entry?.browser).toBeUndefined();
130
+ expect(entry?.import?.default).toBe('./lib/module/toast/index.js');
131
+ });
132
+
133
+ it('the generator no longer lists ./toast as web-forked', () => {
134
+ const generator = readFileSync(
135
+ join(REPO_ROOT, 'scripts/generate-platform-exports.mjs'),
136
+ 'utf8',
137
+ );
138
+ const forkedBlock = /const WEB_FORKED_SUBPATHS = new Set\(\[([\s\S]*?)\]\)/.exec(
139
+ generator,
140
+ );
141
+ expect(forkedBlock).not.toBeNull();
142
+ expect(forkedBlock?.[1]).not.toMatch(/^\s*'\.\/toast',/m);
143
+ });
144
+
145
+ it('no sonner import survives in the toast surface or the root barrel', () => {
146
+ for (const file of [
147
+ 'toast/index.tsx',
148
+ 'toast/Toaster.tsx',
149
+ 'toast/toast-fns.ts',
150
+ 'index.ts',
151
+ ]) {
152
+ expect(code(file)).not.toMatch(/from 'sonner(-native)?'/);
153
+ }
154
+ });
155
+ });