@oxyhq/bloom 0.50.2 → 0.51.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (567) 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/frosted-icon-button/shared.js +1 -1
  12. package/lib/commonjs/index.js +90 -83
  13. package/lib/commonjs/index.js.map +1 -1
  14. package/lib/commonjs/index.web.js +116 -109
  15. package/lib/commonjs/index.web.js.map +1 -1
  16. package/lib/commonjs/menu/index.web.js +2 -1
  17. package/lib/commonjs/menu/index.web.js.map +1 -1
  18. package/lib/commonjs/popover/index.web.js +3 -2
  19. package/lib/commonjs/popover/index.web.js.map +1 -1
  20. package/lib/commonjs/portal/index.js +4 -1
  21. package/lib/commonjs/portal/index.js.map +1 -1
  22. package/lib/commonjs/progressive-blur/index.js +79 -0
  23. package/lib/commonjs/progressive-blur/index.js.map +1 -0
  24. package/lib/commonjs/progressive-blur/index.web.js +67 -0
  25. package/lib/commonjs/progressive-blur/index.web.js.map +1 -0
  26. package/lib/commonjs/progressive-blur/shared.js +66 -0
  27. package/lib/commonjs/progressive-blur/shared.js.map +1 -0
  28. package/lib/commonjs/progressive-blur/types.js +6 -0
  29. package/lib/commonjs/progressive-blur/types.js.map +1 -0
  30. package/lib/commonjs/select/index.web.js +2 -1
  31. package/lib/commonjs/select/index.web.js.map +1 -1
  32. package/lib/commonjs/styles/web-view-style.js +26 -0
  33. package/lib/commonjs/styles/web-view-style.js.map +1 -0
  34. package/lib/commonjs/tab-bar/TabBarBase.js +415 -0
  35. package/lib/commonjs/tab-bar/TabBarBase.js.map +1 -0
  36. package/lib/commonjs/tab-bar/expo-router/RouterTabBar.js +83 -0
  37. package/lib/commonjs/tab-bar/expo-router/RouterTabBar.js.map +1 -0
  38. package/lib/commonjs/tab-bar/expo-router/fading-tab-screen.js +119 -0
  39. package/lib/commonjs/tab-bar/expo-router/fading-tab-screen.js.map +1 -0
  40. package/lib/commonjs/tab-bar/expo-router/index.js +26 -0
  41. package/lib/commonjs/tab-bar/expo-router/index.js.map +1 -0
  42. package/lib/commonjs/tab-bar/glyph.js +43 -0
  43. package/lib/commonjs/tab-bar/glyph.js.map +1 -0
  44. package/lib/commonjs/tab-bar/glyph.native.js +55 -0
  45. package/lib/commonjs/tab-bar/glyph.native.js.map +1 -0
  46. package/lib/commonjs/tab-bar/index.js +65 -0
  47. package/lib/commonjs/tab-bar/index.js.map +1 -0
  48. package/lib/commonjs/tab-bar/index.web.js +67 -0
  49. package/lib/commonjs/tab-bar/index.web.js.map +1 -0
  50. package/lib/commonjs/tab-bar/minimize-context.js +127 -0
  51. package/lib/commonjs/tab-bar/minimize-context.js.map +1 -0
  52. package/lib/commonjs/tab-bar/shared.js +139 -0
  53. package/lib/commonjs/tab-bar/shared.js.map +1 -0
  54. package/lib/commonjs/tab-bar/surface-solid.js +43 -0
  55. package/lib/commonjs/tab-bar/surface-solid.js.map +1 -0
  56. package/lib/commonjs/tab-bar/surface.js +13 -0
  57. package/lib/commonjs/tab-bar/surface.js.map +1 -0
  58. package/lib/commonjs/tab-bar/surface.native.js +113 -0
  59. package/lib/commonjs/tab-bar/surface.native.js.map +1 -0
  60. package/lib/commonjs/tab-bar/surface.web.js +59 -0
  61. package/lib/commonjs/tab-bar/surface.web.js.map +1 -0
  62. package/lib/commonjs/tab-bar/types.js +6 -0
  63. package/lib/commonjs/tab-bar/types.js.map +1 -0
  64. package/lib/commonjs/toast/Positioner.js +117 -0
  65. package/lib/commonjs/toast/Positioner.js.map +1 -0
  66. package/lib/commonjs/toast/ToastContent.js +301 -0
  67. package/lib/commonjs/toast/ToastContent.js.map +1 -0
  68. package/lib/commonjs/toast/ToastHost.js +69 -0
  69. package/lib/commonjs/toast/ToastHost.js.map +1 -0
  70. package/lib/commonjs/toast/ToastHost.native.js +44 -0
  71. package/lib/commonjs/toast/ToastHost.native.js.map +1 -0
  72. package/lib/commonjs/toast/ToastIcon.js +57 -0
  73. package/lib/commonjs/toast/ToastIcon.js.map +1 -0
  74. package/lib/commonjs/toast/ToastRow.js +411 -0
  75. package/lib/commonjs/toast/ToastRow.js.map +1 -0
  76. package/lib/commonjs/toast/ToastSwipeHandler.js +189 -0
  77. package/lib/commonjs/toast/ToastSwipeHandler.js.map +1 -0
  78. package/lib/commonjs/toast/Toaster.js +205 -0
  79. package/lib/commonjs/toast/Toaster.js.map +1 -0
  80. package/lib/commonjs/toast/animations.js +274 -0
  81. package/lib/commonjs/toast/animations.js.map +1 -0
  82. package/lib/commonjs/toast/constants.js +56 -0
  83. package/lib/commonjs/toast/constants.js.map +1 -0
  84. package/lib/commonjs/toast/context.js +42 -0
  85. package/lib/commonjs/toast/context.js.map +1 -0
  86. package/lib/commonjs/toast/index.js +32 -126
  87. package/lib/commonjs/toast/index.js.map +1 -1
  88. package/lib/commonjs/toast/position-utils.js +115 -0
  89. package/lib/commonjs/toast/position-utils.js.map +1 -0
  90. package/lib/commonjs/toast/positioner-utils.js +141 -0
  91. package/lib/commonjs/toast/positioner-utils.js.map +1 -0
  92. package/lib/commonjs/toast/toast-comparator.js +28 -0
  93. package/lib/commonjs/toast/toast-comparator.js.map +1 -0
  94. package/lib/commonjs/toast/toast-fns.js +90 -0
  95. package/lib/commonjs/toast/toast-fns.js.map +1 -0
  96. package/lib/commonjs/toast/toast-store.js +352 -0
  97. package/lib/commonjs/toast/toast-store.js.map +1 -0
  98. package/lib/commonjs/toast/toast-timers.js +110 -0
  99. package/lib/commonjs/toast/toast-timers.js.map +1 -0
  100. package/lib/commonjs/toast/types.js +42 -0
  101. package/lib/commonjs/toast/types.js.map +1 -1
  102. package/lib/commonjs/toast/use-animated-target.js +57 -0
  103. package/lib/commonjs/toast/use-animated-target.js.map +1 -0
  104. package/lib/commonjs/toast/use-app-state.js +76 -0
  105. package/lib/commonjs/toast/use-app-state.js.map +1 -0
  106. package/lib/commonjs/toast/use-toast-colors.js +114 -0
  107. package/lib/commonjs/toast/use-toast-colors.js.map +1 -0
  108. package/lib/commonjs/toast/use-toast-position.js +40 -0
  109. package/lib/commonjs/toast/use-toast-position.js.map +1 -0
  110. package/lib/commonjs/tooltip/index.web.js +2 -1
  111. package/lib/commonjs/tooltip/index.web.js.map +1 -1
  112. package/lib/commonjs/zoomable-image-gallery/ZoomableImageGallery.js +20 -8
  113. package/lib/commonjs/zoomable-image-gallery/ZoomableImageGallery.js.map +1 -1
  114. package/lib/module/avatar-group/AvatarGroup.web.js +2 -1
  115. package/lib/module/avatar-group/AvatarGroup.web.js.map +1 -1
  116. package/lib/module/bottom-sheet/index.web.js +2 -1
  117. package/lib/module/bottom-sheet/index.web.js.map +1 -1
  118. package/lib/module/context-menu/index.web.js +3 -2
  119. package/lib/module/context-menu/index.web.js.map +1 -1
  120. package/lib/module/dialog/Dialog.web.js +4 -3
  121. package/lib/module/dialog/Dialog.web.js.map +1 -1
  122. package/lib/module/frosted-icon-button/shared.js +1 -1
  123. package/lib/module/index.js +3 -2
  124. package/lib/module/index.js.map +1 -1
  125. package/lib/module/index.web.js +3 -2
  126. package/lib/module/index.web.js.map +1 -1
  127. package/lib/module/menu/index.web.js +2 -1
  128. package/lib/module/menu/index.web.js.map +1 -1
  129. package/lib/module/popover/index.web.js +3 -2
  130. package/lib/module/popover/index.web.js.map +1 -1
  131. package/lib/module/portal/index.js +4 -1
  132. package/lib/module/portal/index.js.map +1 -1
  133. package/lib/module/progressive-blur/index.js +74 -0
  134. package/lib/module/progressive-blur/index.js.map +1 -0
  135. package/lib/module/progressive-blur/index.web.js +62 -0
  136. package/lib/module/progressive-blur/index.web.js.map +1 -0
  137. package/lib/module/progressive-blur/shared.js +60 -0
  138. package/lib/module/progressive-blur/shared.js.map +1 -0
  139. package/lib/module/progressive-blur/types.js +4 -0
  140. package/lib/module/progressive-blur/types.js.map +1 -0
  141. package/lib/module/select/index.web.js +2 -1
  142. package/lib/module/select/index.web.js.map +1 -1
  143. package/lib/module/styles/web-view-style.js +22 -0
  144. package/lib/module/styles/web-view-style.js.map +1 -0
  145. package/lib/module/tab-bar/TabBarBase.js +408 -0
  146. package/lib/module/tab-bar/TabBarBase.js.map +1 -0
  147. package/lib/module/tab-bar/expo-router/RouterTabBar.js +78 -0
  148. package/lib/module/tab-bar/expo-router/RouterTabBar.js.map +1 -0
  149. package/lib/module/tab-bar/expo-router/fading-tab-screen.js +113 -0
  150. package/lib/module/tab-bar/expo-router/fading-tab-screen.js.map +1 -0
  151. package/lib/module/tab-bar/expo-router/index.js +15 -0
  152. package/lib/module/tab-bar/expo-router/index.js.map +1 -0
  153. package/lib/module/tab-bar/glyph.js +38 -0
  154. package/lib/module/tab-bar/glyph.js.map +1 -0
  155. package/lib/module/tab-bar/glyph.native.js +50 -0
  156. package/lib/module/tab-bar/glyph.native.js.map +1 -0
  157. package/lib/module/tab-bar/index.js +24 -0
  158. package/lib/module/tab-bar/index.js.map +1 -0
  159. package/lib/module/tab-bar/index.web.js +26 -0
  160. package/lib/module/tab-bar/index.web.js.map +1 -0
  161. package/lib/module/tab-bar/minimize-context.js +118 -0
  162. package/lib/module/tab-bar/minimize-context.js.map +1 -0
  163. package/lib/module/tab-bar/shared.js +132 -0
  164. package/lib/module/tab-bar/shared.js.map +1 -0
  165. package/lib/module/tab-bar/surface-solid.js +37 -0
  166. package/lib/module/tab-bar/surface-solid.js.map +1 -0
  167. package/lib/module/tab-bar/surface.js +31 -0
  168. package/lib/module/tab-bar/surface.js.map +1 -0
  169. package/lib/module/tab-bar/surface.native.js +109 -0
  170. package/lib/module/tab-bar/surface.native.js.map +1 -0
  171. package/lib/module/tab-bar/surface.web.js +53 -0
  172. package/lib/module/tab-bar/surface.web.js.map +1 -0
  173. package/lib/module/tab-bar/types.js +4 -0
  174. package/lib/module/tab-bar/types.js.map +1 -0
  175. package/lib/module/toast/Positioner.js +110 -0
  176. package/lib/module/toast/Positioner.js.map +1 -0
  177. package/lib/module/toast/ToastContent.js +295 -0
  178. package/lib/module/toast/ToastContent.js.map +1 -0
  179. package/lib/module/toast/ToastHost.js +63 -0
  180. package/lib/module/toast/ToastHost.js.map +1 -0
  181. package/lib/module/toast/ToastHost.native.js +38 -0
  182. package/lib/module/toast/ToastHost.native.js.map +1 -0
  183. package/lib/module/toast/ToastIcon.js +52 -0
  184. package/lib/module/toast/ToastIcon.js.map +1 -0
  185. package/lib/module/toast/ToastRow.js +407 -0
  186. package/lib/module/toast/ToastRow.js.map +1 -0
  187. package/lib/module/toast/ToastSwipeHandler.js +182 -0
  188. package/lib/module/toast/ToastSwipeHandler.js.map +1 -0
  189. package/lib/module/toast/Toaster.js +198 -0
  190. package/lib/module/toast/Toaster.js.map +1 -0
  191. package/lib/module/toast/animations.js +261 -0
  192. package/lib/module/toast/animations.js.map +1 -0
  193. package/lib/module/toast/constants.js +52 -0
  194. package/lib/module/toast/constants.js.map +1 -0
  195. package/lib/module/toast/context.js +34 -0
  196. package/lib/module/toast/context.js.map +1 -0
  197. package/lib/module/toast/index.js +27 -103
  198. package/lib/module/toast/index.js.map +1 -1
  199. package/lib/module/toast/position-utils.js +107 -0
  200. package/lib/module/toast/position-utils.js.map +1 -0
  201. package/lib/module/toast/positioner-utils.js +134 -0
  202. package/lib/module/toast/positioner-utils.js.map +1 -0
  203. package/lib/module/toast/toast-comparator.js +22 -0
  204. package/lib/module/toast/toast-comparator.js.map +1 -0
  205. package/lib/module/toast/toast-fns.js +85 -0
  206. package/lib/module/toast/toast-fns.js.map +1 -0
  207. package/lib/module/toast/toast-store.js +346 -0
  208. package/lib/module/toast/toast-store.js.map +1 -0
  209. package/lib/module/toast/toast-timers.js +104 -0
  210. package/lib/module/toast/toast-timers.js.map +1 -0
  211. package/lib/module/toast/types.js +38 -0
  212. package/lib/module/toast/types.js.map +1 -1
  213. package/lib/module/toast/use-animated-target.js +52 -0
  214. package/lib/module/toast/use-animated-target.js.map +1 -0
  215. package/lib/module/toast/use-app-state.js +70 -0
  216. package/lib/module/toast/use-app-state.js.map +1 -0
  217. package/lib/module/toast/use-toast-colors.js +109 -0
  218. package/lib/module/toast/use-toast-colors.js.map +1 -0
  219. package/lib/module/toast/use-toast-position.js +35 -0
  220. package/lib/module/toast/use-toast-position.js.map +1 -0
  221. package/lib/module/tooltip/index.web.js +2 -1
  222. package/lib/module/tooltip/index.web.js.map +1 -1
  223. package/lib/module/zoomable-image-gallery/ZoomableImageGallery.js +20 -8
  224. package/lib/module/zoomable-image-gallery/ZoomableImageGallery.js.map +1 -1
  225. package/lib/typescript/commonjs/avatar-group/AvatarGroup.web.d.ts.map +1 -1
  226. package/lib/typescript/commonjs/benefit-list/types.d.ts +2 -1
  227. package/lib/typescript/commonjs/benefit-list/types.d.ts.map +1 -1
  228. package/lib/typescript/commonjs/bottom-sheet/index.web.d.ts.map +1 -1
  229. package/lib/typescript/commonjs/context-menu/index.web.d.ts.map +1 -1
  230. package/lib/typescript/commonjs/dialog/Dialog.web.d.ts.map +1 -1
  231. package/lib/typescript/commonjs/fab/types.d.ts +4 -2
  232. package/lib/typescript/commonjs/fab/types.d.ts.map +1 -1
  233. package/lib/typescript/commonjs/frosted-icon-button/shared.d.ts +1 -1
  234. package/lib/typescript/commonjs/frosted-icon-button/types.d.ts +2 -1
  235. package/lib/typescript/commonjs/frosted-icon-button/types.d.ts.map +1 -1
  236. package/lib/typescript/commonjs/index.d.ts +2 -1
  237. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  238. package/lib/typescript/commonjs/index.web.d.ts +2 -1
  239. package/lib/typescript/commonjs/index.web.d.ts.map +1 -1
  240. package/lib/typescript/commonjs/menu/index.web.d.ts.map +1 -1
  241. package/lib/typescript/commonjs/popover/index.web.d.ts.map +1 -1
  242. package/lib/typescript/commonjs/portal/index.d.ts.map +1 -1
  243. package/lib/typescript/commonjs/progressive-blur/index.d.ts +23 -0
  244. package/lib/typescript/commonjs/progressive-blur/index.d.ts.map +1 -0
  245. package/lib/typescript/commonjs/progressive-blur/index.web.d.ts +30 -0
  246. package/lib/typescript/commonjs/progressive-blur/index.web.d.ts.map +1 -0
  247. package/lib/typescript/commonjs/progressive-blur/shared.d.ts +35 -0
  248. package/lib/typescript/commonjs/progressive-blur/shared.d.ts.map +1 -0
  249. package/lib/typescript/commonjs/progressive-blur/types.d.ts +21 -0
  250. package/lib/typescript/commonjs/progressive-blur/types.d.ts.map +1 -0
  251. package/lib/typescript/commonjs/select/index.web.d.ts.map +1 -1
  252. package/lib/typescript/commonjs/styles/web-view-style.d.ts +21 -0
  253. package/lib/typescript/commonjs/styles/web-view-style.d.ts.map +1 -0
  254. package/lib/typescript/commonjs/tab-bar/TabBarBase.d.ts +36 -0
  255. package/lib/typescript/commonjs/tab-bar/TabBarBase.d.ts.map +1 -0
  256. package/lib/typescript/commonjs/tab-bar/expo-router/RouterTabBar.d.ts +59 -0
  257. package/lib/typescript/commonjs/tab-bar/expo-router/RouterTabBar.d.ts.map +1 -0
  258. package/lib/typescript/commonjs/tab-bar/expo-router/fading-tab-screen.d.ts +11 -0
  259. package/lib/typescript/commonjs/tab-bar/expo-router/fading-tab-screen.d.ts.map +1 -0
  260. package/lib/typescript/commonjs/tab-bar/expo-router/index.d.ts +14 -0
  261. package/lib/typescript/commonjs/tab-bar/expo-router/index.d.ts.map +1 -0
  262. package/lib/typescript/commonjs/tab-bar/glyph.d.ts +6 -0
  263. package/lib/typescript/commonjs/tab-bar/glyph.d.ts.map +1 -0
  264. package/lib/typescript/commonjs/tab-bar/glyph.native.d.ts +6 -0
  265. package/lib/typescript/commonjs/tab-bar/glyph.native.d.ts.map +1 -0
  266. package/lib/typescript/commonjs/tab-bar/index.d.ts +12 -0
  267. package/lib/typescript/commonjs/tab-bar/index.d.ts.map +1 -0
  268. package/lib/typescript/commonjs/tab-bar/index.web.d.ts +12 -0
  269. package/lib/typescript/commonjs/tab-bar/index.web.d.ts.map +1 -0
  270. package/lib/typescript/commonjs/tab-bar/minimize-context.d.ts +51 -0
  271. package/lib/typescript/commonjs/tab-bar/minimize-context.d.ts.map +1 -0
  272. package/lib/typescript/commonjs/tab-bar/shared.d.ts +93 -0
  273. package/lib/typescript/commonjs/tab-bar/shared.d.ts.map +1 -0
  274. package/lib/typescript/commonjs/tab-bar/surface-solid.d.ts +6 -0
  275. package/lib/typescript/commonjs/tab-bar/surface-solid.d.ts.map +1 -0
  276. package/lib/typescript/commonjs/tab-bar/surface.d.ts +29 -0
  277. package/lib/typescript/commonjs/tab-bar/surface.d.ts.map +1 -0
  278. package/lib/typescript/commonjs/tab-bar/surface.native.d.ts +6 -0
  279. package/lib/typescript/commonjs/tab-bar/surface.native.d.ts.map +1 -0
  280. package/lib/typescript/commonjs/tab-bar/surface.web.d.ts +6 -0
  281. package/lib/typescript/commonjs/tab-bar/surface.web.d.ts.map +1 -0
  282. package/lib/typescript/commonjs/tab-bar/types.d.ts +88 -0
  283. package/lib/typescript/commonjs/tab-bar/types.d.ts.map +1 -0
  284. package/lib/typescript/commonjs/toast/Positioner.d.ts +21 -0
  285. package/lib/typescript/commonjs/toast/Positioner.d.ts.map +1 -0
  286. package/lib/typescript/commonjs/toast/ToastContent.d.ts +14 -0
  287. package/lib/typescript/commonjs/toast/ToastContent.d.ts.map +1 -0
  288. package/lib/typescript/commonjs/toast/ToastHost.d.ts +6 -0
  289. package/lib/typescript/commonjs/toast/ToastHost.d.ts.map +1 -0
  290. package/lib/typescript/commonjs/toast/ToastHost.native.d.ts +6 -0
  291. package/lib/typescript/commonjs/toast/ToastHost.native.d.ts.map +1 -0
  292. package/lib/typescript/commonjs/toast/ToastIcon.d.ts +9 -0
  293. package/lib/typescript/commonjs/toast/ToastIcon.d.ts.map +1 -0
  294. package/lib/typescript/commonjs/toast/ToastRow.d.ts +80 -0
  295. package/lib/typescript/commonjs/toast/ToastRow.d.ts.map +1 -0
  296. package/lib/typescript/commonjs/toast/ToastSwipeHandler.d.ts +30 -0
  297. package/lib/typescript/commonjs/toast/ToastSwipeHandler.d.ts.map +1 -0
  298. package/lib/typescript/commonjs/toast/Toaster.d.ts +19 -0
  299. package/lib/typescript/commonjs/toast/Toaster.d.ts.map +1 -0
  300. package/lib/typescript/commonjs/toast/animations.d.ts +62 -0
  301. package/lib/typescript/commonjs/toast/animations.d.ts.map +1 -0
  302. package/lib/typescript/commonjs/toast/constants.d.ts +39 -0
  303. package/lib/typescript/commonjs/toast/constants.d.ts.map +1 -0
  304. package/lib/typescript/commonjs/toast/context.d.ts +19 -0
  305. package/lib/typescript/commonjs/toast/context.d.ts.map +1 -0
  306. package/lib/typescript/commonjs/toast/index.d.ts +23 -76
  307. package/lib/typescript/commonjs/toast/index.d.ts.map +1 -1
  308. package/lib/typescript/commonjs/toast/position-utils.d.ts +30 -0
  309. package/lib/typescript/commonjs/toast/position-utils.d.ts.map +1 -0
  310. package/lib/typescript/commonjs/toast/positioner-utils.d.ts +72 -0
  311. package/lib/typescript/commonjs/toast/positioner-utils.d.ts.map +1 -0
  312. package/lib/typescript/commonjs/toast/toast-comparator.d.ts +12 -0
  313. package/lib/typescript/commonjs/toast/toast-comparator.d.ts.map +1 -0
  314. package/lib/typescript/commonjs/toast/toast-fns.d.ts +3 -0
  315. package/lib/typescript/commonjs/toast/toast-fns.d.ts.map +1 -0
  316. package/lib/typescript/commonjs/toast/toast-store.d.ts +52 -0
  317. package/lib/typescript/commonjs/toast/toast-store.d.ts.map +1 -0
  318. package/lib/typescript/commonjs/toast/toast-timers.d.ts +24 -0
  319. package/lib/typescript/commonjs/toast/toast-timers.d.ts.map +1 -0
  320. package/lib/typescript/commonjs/toast/types.d.ts +222 -5
  321. package/lib/typescript/commonjs/toast/types.d.ts.map +1 -1
  322. package/lib/typescript/commonjs/toast/use-animated-target.d.ts +7 -0
  323. package/lib/typescript/commonjs/toast/use-animated-target.d.ts.map +1 -0
  324. package/lib/typescript/commonjs/toast/use-app-state.d.ts +18 -0
  325. package/lib/typescript/commonjs/toast/use-app-state.d.ts.map +1 -0
  326. package/lib/typescript/commonjs/toast/use-toast-colors.d.ts +22 -0
  327. package/lib/typescript/commonjs/toast/use-toast-colors.d.ts.map +1 -0
  328. package/lib/typescript/commonjs/toast/use-toast-position.d.ts +37 -0
  329. package/lib/typescript/commonjs/toast/use-toast-position.d.ts.map +1 -0
  330. package/lib/typescript/commonjs/tooltip/index.web.d.ts.map +1 -1
  331. package/lib/typescript/commonjs/zoomable-image-gallery/ZoomableImageGallery.d.ts.map +1 -1
  332. package/lib/typescript/module/avatar-group/AvatarGroup.web.d.ts.map +1 -1
  333. package/lib/typescript/module/benefit-list/types.d.ts +2 -1
  334. package/lib/typescript/module/benefit-list/types.d.ts.map +1 -1
  335. package/lib/typescript/module/bottom-sheet/index.web.d.ts.map +1 -1
  336. package/lib/typescript/module/context-menu/index.web.d.ts.map +1 -1
  337. package/lib/typescript/module/dialog/Dialog.web.d.ts.map +1 -1
  338. package/lib/typescript/module/fab/types.d.ts +4 -2
  339. package/lib/typescript/module/fab/types.d.ts.map +1 -1
  340. package/lib/typescript/module/frosted-icon-button/shared.d.ts +1 -1
  341. package/lib/typescript/module/frosted-icon-button/types.d.ts +2 -1
  342. package/lib/typescript/module/frosted-icon-button/types.d.ts.map +1 -1
  343. package/lib/typescript/module/index.d.ts +2 -1
  344. package/lib/typescript/module/index.d.ts.map +1 -1
  345. package/lib/typescript/module/index.web.d.ts +2 -1
  346. package/lib/typescript/module/index.web.d.ts.map +1 -1
  347. package/lib/typescript/module/menu/index.web.d.ts.map +1 -1
  348. package/lib/typescript/module/popover/index.web.d.ts.map +1 -1
  349. package/lib/typescript/module/portal/index.d.ts.map +1 -1
  350. package/lib/typescript/module/progressive-blur/index.d.ts +23 -0
  351. package/lib/typescript/module/progressive-blur/index.d.ts.map +1 -0
  352. package/lib/typescript/module/progressive-blur/index.web.d.ts +30 -0
  353. package/lib/typescript/module/progressive-blur/index.web.d.ts.map +1 -0
  354. package/lib/typescript/module/progressive-blur/shared.d.ts +35 -0
  355. package/lib/typescript/module/progressive-blur/shared.d.ts.map +1 -0
  356. package/lib/typescript/module/progressive-blur/types.d.ts +21 -0
  357. package/lib/typescript/module/progressive-blur/types.d.ts.map +1 -0
  358. package/lib/typescript/module/select/index.web.d.ts.map +1 -1
  359. package/lib/typescript/module/styles/web-view-style.d.ts +21 -0
  360. package/lib/typescript/module/styles/web-view-style.d.ts.map +1 -0
  361. package/lib/typescript/module/tab-bar/TabBarBase.d.ts +36 -0
  362. package/lib/typescript/module/tab-bar/TabBarBase.d.ts.map +1 -0
  363. package/lib/typescript/module/tab-bar/expo-router/RouterTabBar.d.ts +59 -0
  364. package/lib/typescript/module/tab-bar/expo-router/RouterTabBar.d.ts.map +1 -0
  365. package/lib/typescript/module/tab-bar/expo-router/fading-tab-screen.d.ts +11 -0
  366. package/lib/typescript/module/tab-bar/expo-router/fading-tab-screen.d.ts.map +1 -0
  367. package/lib/typescript/module/tab-bar/expo-router/index.d.ts +14 -0
  368. package/lib/typescript/module/tab-bar/expo-router/index.d.ts.map +1 -0
  369. package/lib/typescript/module/tab-bar/glyph.d.ts +6 -0
  370. package/lib/typescript/module/tab-bar/glyph.d.ts.map +1 -0
  371. package/lib/typescript/module/tab-bar/glyph.native.d.ts +6 -0
  372. package/lib/typescript/module/tab-bar/glyph.native.d.ts.map +1 -0
  373. package/lib/typescript/module/tab-bar/index.d.ts +12 -0
  374. package/lib/typescript/module/tab-bar/index.d.ts.map +1 -0
  375. package/lib/typescript/module/tab-bar/index.web.d.ts +12 -0
  376. package/lib/typescript/module/tab-bar/index.web.d.ts.map +1 -0
  377. package/lib/typescript/module/tab-bar/minimize-context.d.ts +51 -0
  378. package/lib/typescript/module/tab-bar/minimize-context.d.ts.map +1 -0
  379. package/lib/typescript/module/tab-bar/shared.d.ts +93 -0
  380. package/lib/typescript/module/tab-bar/shared.d.ts.map +1 -0
  381. package/lib/typescript/module/tab-bar/surface-solid.d.ts +6 -0
  382. package/lib/typescript/module/tab-bar/surface-solid.d.ts.map +1 -0
  383. package/lib/typescript/module/tab-bar/surface.d.ts +29 -0
  384. package/lib/typescript/module/tab-bar/surface.d.ts.map +1 -0
  385. package/lib/typescript/module/tab-bar/surface.native.d.ts +6 -0
  386. package/lib/typescript/module/tab-bar/surface.native.d.ts.map +1 -0
  387. package/lib/typescript/module/tab-bar/surface.web.d.ts +6 -0
  388. package/lib/typescript/module/tab-bar/surface.web.d.ts.map +1 -0
  389. package/lib/typescript/module/tab-bar/types.d.ts +88 -0
  390. package/lib/typescript/module/tab-bar/types.d.ts.map +1 -0
  391. package/lib/typescript/module/toast/Positioner.d.ts +21 -0
  392. package/lib/typescript/module/toast/Positioner.d.ts.map +1 -0
  393. package/lib/typescript/module/toast/ToastContent.d.ts +14 -0
  394. package/lib/typescript/module/toast/ToastContent.d.ts.map +1 -0
  395. package/lib/typescript/module/toast/ToastHost.d.ts +6 -0
  396. package/lib/typescript/module/toast/ToastHost.d.ts.map +1 -0
  397. package/lib/typescript/module/toast/ToastHost.native.d.ts +6 -0
  398. package/lib/typescript/module/toast/ToastHost.native.d.ts.map +1 -0
  399. package/lib/typescript/module/toast/ToastIcon.d.ts +9 -0
  400. package/lib/typescript/module/toast/ToastIcon.d.ts.map +1 -0
  401. package/lib/typescript/module/toast/ToastRow.d.ts +80 -0
  402. package/lib/typescript/module/toast/ToastRow.d.ts.map +1 -0
  403. package/lib/typescript/module/toast/ToastSwipeHandler.d.ts +30 -0
  404. package/lib/typescript/module/toast/ToastSwipeHandler.d.ts.map +1 -0
  405. package/lib/typescript/module/toast/Toaster.d.ts +19 -0
  406. package/lib/typescript/module/toast/Toaster.d.ts.map +1 -0
  407. package/lib/typescript/module/toast/animations.d.ts +62 -0
  408. package/lib/typescript/module/toast/animations.d.ts.map +1 -0
  409. package/lib/typescript/module/toast/constants.d.ts +39 -0
  410. package/lib/typescript/module/toast/constants.d.ts.map +1 -0
  411. package/lib/typescript/module/toast/context.d.ts +19 -0
  412. package/lib/typescript/module/toast/context.d.ts.map +1 -0
  413. package/lib/typescript/module/toast/index.d.ts +23 -76
  414. package/lib/typescript/module/toast/index.d.ts.map +1 -1
  415. package/lib/typescript/module/toast/position-utils.d.ts +30 -0
  416. package/lib/typescript/module/toast/position-utils.d.ts.map +1 -0
  417. package/lib/typescript/module/toast/positioner-utils.d.ts +72 -0
  418. package/lib/typescript/module/toast/positioner-utils.d.ts.map +1 -0
  419. package/lib/typescript/module/toast/toast-comparator.d.ts +12 -0
  420. package/lib/typescript/module/toast/toast-comparator.d.ts.map +1 -0
  421. package/lib/typescript/module/toast/toast-fns.d.ts +3 -0
  422. package/lib/typescript/module/toast/toast-fns.d.ts.map +1 -0
  423. package/lib/typescript/module/toast/toast-store.d.ts +52 -0
  424. package/lib/typescript/module/toast/toast-store.d.ts.map +1 -0
  425. package/lib/typescript/module/toast/toast-timers.d.ts +24 -0
  426. package/lib/typescript/module/toast/toast-timers.d.ts.map +1 -0
  427. package/lib/typescript/module/toast/types.d.ts +222 -5
  428. package/lib/typescript/module/toast/types.d.ts.map +1 -1
  429. package/lib/typescript/module/toast/use-animated-target.d.ts +7 -0
  430. package/lib/typescript/module/toast/use-animated-target.d.ts.map +1 -0
  431. package/lib/typescript/module/toast/use-app-state.d.ts +18 -0
  432. package/lib/typescript/module/toast/use-app-state.d.ts.map +1 -0
  433. package/lib/typescript/module/toast/use-toast-colors.d.ts +22 -0
  434. package/lib/typescript/module/toast/use-toast-colors.d.ts.map +1 -0
  435. package/lib/typescript/module/toast/use-toast-position.d.ts +37 -0
  436. package/lib/typescript/module/toast/use-toast-position.d.ts.map +1 -0
  437. package/lib/typescript/module/tooltip/index.web.d.ts.map +1 -1
  438. package/lib/typescript/module/zoomable-image-gallery/ZoomableImageGallery.d.ts.map +1 -1
  439. package/package.json +58 -26
  440. package/src/__tests__/TabBar.test.tsx +342 -0
  441. package/src/__tests__/TabBarGlassFallback.test.tsx +234 -0
  442. package/src/__tests__/TabBarReanimatedDeps.test.ts +130 -0
  443. package/src/__tests__/TabBarWebFork.test.ts +243 -0
  444. package/src/__tests__/ToastContent.test.tsx +192 -0
  445. package/src/__tests__/ToastHostWebFork.test.ts +155 -0
  446. package/src/__tests__/Toaster.test.tsx +527 -0
  447. package/src/__tests__/animated-style-deps.test.ts +156 -0
  448. package/src/__tests__/icon-references.test.ts +243 -0
  449. package/src/__tests__/toast-animations.test.ts +98 -0
  450. package/src/__tests__/toast-comparator.test.ts +131 -0
  451. package/src/__tests__/toast-enter-driver.test.ts +147 -0
  452. package/src/__tests__/toast-fns.test.ts +240 -0
  453. package/src/__tests__/toast-position-utils.test.ts +259 -0
  454. package/src/__tests__/toast-positioner-utils.test.ts +214 -0
  455. package/src/__tests__/toast-store.test.ts +622 -0
  456. package/src/__tests__/toast-timers.test.ts +163 -0
  457. package/src/__tests__/use-animated-target.test.tsx +60 -0
  458. package/src/__tests__/use-app-state.test.tsx +127 -0
  459. package/src/__tests__/use-toast-colors.test.tsx +189 -0
  460. package/src/__tests__/web-position-fixed.test.ts +70 -0
  461. package/src/avatar-group/AvatarGroup.web.tsx +2 -1
  462. package/src/benefit-list/types.ts +2 -1
  463. package/src/bottom-sheet/index.web.tsx +3 -2
  464. package/src/context-menu/index.web.tsx +3 -2
  465. package/src/dialog/Dialog.web.tsx +4 -3
  466. package/src/fab/types.ts +4 -2
  467. package/src/frosted-icon-button/shared.ts +1 -1
  468. package/src/frosted-icon-button/types.ts +2 -1
  469. package/src/index.ts +4 -1
  470. package/src/index.web.ts +4 -1
  471. package/src/menu/index.web.tsx +2 -1
  472. package/src/popover/index.web.tsx +3 -2
  473. package/src/portal/index.tsx +4 -1
  474. package/src/progressive-blur/index.tsx +78 -0
  475. package/src/progressive-blur/index.web.tsx +65 -0
  476. package/src/progressive-blur/shared.ts +81 -0
  477. package/src/progressive-blur/types.ts +21 -0
  478. package/src/select/index.web.tsx +2 -1
  479. package/src/styles/web-view-style.ts +21 -0
  480. package/src/tab-bar/TabBar.stories.tsx +217 -0
  481. package/src/tab-bar/TabBarBase.tsx +517 -0
  482. package/src/tab-bar/expo-router/RouterTabBar.tsx +80 -0
  483. package/src/tab-bar/expo-router/fading-tab-screen.tsx +109 -0
  484. package/src/tab-bar/expo-router/index.ts +13 -0
  485. package/src/tab-bar/glyph.native.tsx +46 -0
  486. package/src/tab-bar/glyph.tsx +31 -0
  487. package/src/tab-bar/index.ts +32 -0
  488. package/src/tab-bar/index.web.tsx +34 -0
  489. package/src/tab-bar/minimize-context.tsx +117 -0
  490. package/src/tab-bar/shared.ts +159 -0
  491. package/src/tab-bar/surface-solid.tsx +40 -0
  492. package/src/tab-bar/surface.native.tsx +122 -0
  493. package/src/tab-bar/surface.tsx +28 -0
  494. package/src/tab-bar/surface.web.tsx +56 -0
  495. package/src/tab-bar/types.ts +91 -0
  496. package/src/toast/Positioner.tsx +121 -0
  497. package/src/toast/Toast.stories.tsx +292 -65
  498. package/src/toast/ToastContent.tsx +405 -0
  499. package/src/toast/ToastHost.native.tsx +31 -0
  500. package/src/toast/ToastHost.tsx +67 -0
  501. package/src/toast/ToastIcon.tsx +55 -0
  502. package/src/toast/ToastRow.tsx +485 -0
  503. package/src/toast/ToastSwipeHandler.tsx +222 -0
  504. package/src/toast/Toaster.tsx +259 -0
  505. package/src/toast/animations.ts +313 -0
  506. package/src/toast/constants.ts +76 -0
  507. package/src/toast/context.tsx +44 -0
  508. package/src/toast/index.tsx +47 -123
  509. package/src/toast/position-utils.ts +149 -0
  510. package/src/toast/positioner-utils.ts +142 -0
  511. package/src/toast/toast-comparator.ts +41 -0
  512. package/src/toast/toast-fns.ts +104 -0
  513. package/src/toast/toast-store.ts +432 -0
  514. package/src/toast/toast-timers.ts +124 -0
  515. package/src/toast/types.ts +301 -5
  516. package/src/toast/use-animated-target.ts +61 -0
  517. package/src/toast/use-app-state.ts +77 -0
  518. package/src/toast/use-toast-colors.ts +133 -0
  519. package/src/toast/use-toast-position.ts +46 -0
  520. package/src/tooltip/index.web.tsx +2 -1
  521. package/src/zoomable-image-gallery/ZoomableImageGallery.stories.tsx +134 -0
  522. package/src/zoomable-image-gallery/ZoomableImageGallery.tsx +50 -27
  523. package/lib/commonjs/toast/Toast.js +0 -267
  524. package/lib/commonjs/toast/Toast.js.map +0 -1
  525. package/lib/commonjs/toast/const.js +0 -8
  526. package/lib/commonjs/toast/const.js.map +0 -1
  527. package/lib/commonjs/toast/index.web.js +0 -114
  528. package/lib/commonjs/toast/index.web.js.map +0 -1
  529. package/lib/commonjs/toast/sonner/index.js +0 -9
  530. package/lib/commonjs/toast/sonner/index.js.map +0 -1
  531. package/lib/commonjs/toast/sonner/index.web.js +0 -9
  532. package/lib/commonjs/toast/sonner/index.web.js.map +0 -1
  533. package/lib/module/toast/Toast.js +0 -258
  534. package/lib/module/toast/Toast.js.map +0 -1
  535. package/lib/module/toast/const.js +0 -4
  536. package/lib/module/toast/const.js.map +0 -1
  537. package/lib/module/toast/index.web.js +0 -74
  538. package/lib/module/toast/index.web.js.map +0 -1
  539. package/lib/module/toast/sonner/index.js +0 -5
  540. package/lib/module/toast/sonner/index.js.map +0 -1
  541. package/lib/module/toast/sonner/index.web.js +0 -5
  542. package/lib/module/toast/sonner/index.web.js.map +0 -1
  543. package/lib/typescript/commonjs/toast/Toast.d.ts +0 -23
  544. package/lib/typescript/commonjs/toast/Toast.d.ts.map +0 -1
  545. package/lib/typescript/commonjs/toast/const.d.ts +0 -2
  546. package/lib/typescript/commonjs/toast/const.d.ts.map +0 -1
  547. package/lib/typescript/commonjs/toast/index.web.d.ts +0 -29
  548. package/lib/typescript/commonjs/toast/index.web.d.ts.map +0 -1
  549. package/lib/typescript/commonjs/toast/sonner/index.d.ts +0 -2
  550. package/lib/typescript/commonjs/toast/sonner/index.d.ts.map +0 -1
  551. package/lib/typescript/commonjs/toast/sonner/index.web.d.ts +0 -2
  552. package/lib/typescript/commonjs/toast/sonner/index.web.d.ts.map +0 -1
  553. package/lib/typescript/module/toast/Toast.d.ts +0 -23
  554. package/lib/typescript/module/toast/Toast.d.ts.map +0 -1
  555. package/lib/typescript/module/toast/const.d.ts +0 -2
  556. package/lib/typescript/module/toast/const.d.ts.map +0 -1
  557. package/lib/typescript/module/toast/index.web.d.ts +0 -29
  558. package/lib/typescript/module/toast/index.web.d.ts.map +0 -1
  559. package/lib/typescript/module/toast/sonner/index.d.ts +0 -2
  560. package/lib/typescript/module/toast/sonner/index.d.ts.map +0 -1
  561. package/lib/typescript/module/toast/sonner/index.web.d.ts +0 -2
  562. package/lib/typescript/module/toast/sonner/index.web.d.ts.map +0 -1
  563. package/src/toast/Toast.tsx +0 -269
  564. package/src/toast/const.ts +0 -1
  565. package/src/toast/index.web.tsx +0 -101
  566. package/src/toast/sonner/index.ts +0 -3
  567. package/src/toast/sonner/index.web.ts +0 -3
@@ -0,0 +1,243 @@
1
+ import { readFileSync, readdirSync, statSync } from 'node:fs';
2
+ import { extname, join, relative } from 'node:path';
3
+
4
+ /**
5
+ * Every `Icons.*` reference in this repo must name an identifier `src/icons`
6
+ * actually exports.
7
+ *
8
+ * Icon exports carry their full style and corner suffix
9
+ * (`Home_Stroke2_Corner0_Rounded`), there are 250-odd of them, and a shortened
10
+ * name is not a compile error anywhere it usually appears: in a DOC COMMENT or an
11
+ * `.mdx` example, `tsc` never sees it. A reader copies it, gets `undefined`, and
12
+ * React reports "Element type is invalid … but got: undefined" against the
13
+ * consumer's own file — which is exactly how a phantom release blocker was filed
14
+ * against the tab bar's native surface.
15
+ *
16
+ * Two shapes are checked, because the real incident needed both:
17
+ *
18
+ * 1. `Icons.Home` — a member that does not exist.
19
+ * 2. `import { Icons } from '@oxyhq/bloom/icons'` — the NAMESPACE imported as a
20
+ * named export. `Icons` is assembled by the ROOT barrel
21
+ * (`export * as Icons from './icons'` in `src/index.ts`); the `./icons`
22
+ * subpath exports the components flat, so that import is `undefined` too.
23
+ * `import * as Icons from '@oxyhq/bloom/icons'` and
24
+ * `import { Icons } from '@oxyhq/bloom'` are both correct and must stay
25
+ * unflagged.
26
+ *
27
+ * Comments are deliberately NOT stripped here — the inverse of
28
+ * `TabBarWebFork.test.ts`, which blanks them so a doc comment naming a package is
29
+ * not mistaken for an import of it. Here the doc comments ARE the surface under
30
+ * test: four of the five instances this test was written for lived in JSDoc.
31
+ *
32
+ * Identifiers are matched against the UNION of everything exported anywhere under
33
+ * `src/icons`, because references legitimately target the barrel
34
+ * (`../icons`), a single icon file (`../icons/Check`) and `../icons/common` alike.
35
+ */
36
+
37
+ const SRC = join(__dirname, '..');
38
+ const REPO_ROOT = join(SRC, '..');
39
+ const ICONS_DIR = join(SRC, 'icons');
40
+
41
+ const SCANNED_EXTENSIONS = ['.ts', '.tsx', '.mdx', '.md'];
42
+
43
+ /** True for a specifier that resolves to an icons module, package or relative. */
44
+ const ICONS_MODULE = /(?:^|\/)icons(?:\/|$)/;
45
+
46
+ function walk(dir: string, out: string[] = []): string[] {
47
+ for (const entry of readdirSync(dir)) {
48
+ // Agent worktrees under `.claude/` are full copies of this repo — scanning
49
+ // them would double every file and report another checkout's problems.
50
+ if (entry === 'node_modules' || entry === 'lib' || entry.startsWith('.')) continue;
51
+ const full = join(dir, entry);
52
+ if (statSync(full).isDirectory()) walk(full, out);
53
+ else if (SCANNED_EXTENSIONS.includes(extname(full))) out.push(full);
54
+ }
55
+ return out;
56
+ }
57
+
58
+ /** Every identifier a module exports, across every export shape in use here. */
59
+ function exportedNames(source: string): string[] {
60
+ const found = new Set<string>();
61
+
62
+ // `export const X` / `export function X` / `export class X` /
63
+ // `export type X =` / `export interface X`
64
+ for (const m of source.matchAll(
65
+ /export\s+(?:declare\s+)?(?:const|let|var|function|class|type|interface)\s+([A-Za-z0-9_$]+)/g,
66
+ )) {
67
+ if (m[1]) found.add(m[1]);
68
+ }
69
+
70
+ // `export { A, B as C }` and `export type { A, B } from './x'` — the form that
71
+ // carries `IconStyle` / `Props` out of `icons/common.tsx` through the barrel.
72
+ // Missing it is what made an earlier pass of this check report two phantom
73
+ // failures, and a check with known noise is a check somebody disables.
74
+ for (const m of source.matchAll(/export\s+(?:type\s+)?\{([^}]*)\}/g)) {
75
+ for (const name of namedBindings(m[1] ?? '', 'export')) found.add(name);
76
+ }
77
+
78
+ return [...found];
79
+ }
80
+
81
+ /**
82
+ * The bindings a brace list introduces.
83
+ *
84
+ * `as` means opposite things in the two directions: `export { A as B }` publishes
85
+ * `B`, while `import { A as B }` reads `A`. Getting that backwards would make the
86
+ * check blind to exactly the imports it exists to catch.
87
+ */
88
+ function namedBindings(list: string, direction: 'import' | 'export'): string[] {
89
+ const names: string[] = [];
90
+ for (const raw of list.split(',')) {
91
+ const part = raw.trim().replace(/^type\s+/, '');
92
+ if (!part) continue;
93
+ const sides = part.split(/\s+as\s+/).map((s) => s.trim());
94
+ const name = direction === 'export' ? sides[sides.length - 1] : sides[0];
95
+ if (name && /^[A-Za-z0-9_$]+$/.test(name) && name !== 'default') names.push(name);
96
+ }
97
+ return names;
98
+ }
99
+
100
+ /** The union of every identifier exported anywhere under `src/icons`. */
101
+ function iconExportUnion(): Set<string> {
102
+ const union = new Set<string>();
103
+ for (const file of walk(ICONS_DIR)) {
104
+ for (const name of exportedNames(readFileSync(file, 'utf8'))) union.add(name);
105
+ }
106
+ return union;
107
+ }
108
+
109
+ interface Unresolved {
110
+ line: number;
111
+ ref: string;
112
+ }
113
+
114
+ /** Every icon reference in `source` that `exported` cannot satisfy. */
115
+ function unresolvedIconRefs(source: string, exported: Set<string>): Unresolved[] {
116
+ const problems: Unresolved[] = [];
117
+
118
+ source.split('\n').forEach((text, index) => {
119
+ const line = index + 1;
120
+
121
+ for (const m of text.matchAll(/\bIcons\.([A-Za-z0-9_$]+)/g)) {
122
+ if (m[1] && !exported.has(m[1])) problems.push({ line, ref: `Icons.${m[1]}` });
123
+ }
124
+
125
+ // Braces only: `import * as Icons from …` is the correct namespace form, and a
126
+ // bare `import '…/icons'` binds nothing.
127
+ const imported = /\bimport\s+(?:type\s+)?\{([^}]*)\}\s*from\s*['"]([^'"]+)['"]/.exec(text);
128
+ const specifier = imported?.[2];
129
+ if (imported && specifier && ICONS_MODULE.test(specifier)) {
130
+ for (const name of namedBindings(imported[1] ?? '', 'import')) {
131
+ if (!exported.has(name)) problems.push({ line, ref: `{ ${name} } from '${specifier}'` });
132
+ }
133
+ }
134
+ });
135
+
136
+ return problems;
137
+ }
138
+
139
+ const ICON_EXPORTS = iconExportUnion();
140
+
141
+ const SCANNED = [
142
+ ...walk(SRC),
143
+ ...walk(join(REPO_ROOT, 'docs')),
144
+ join(REPO_ROOT, 'README.md'),
145
+ join(REPO_ROOT, 'AGENTS.md'),
146
+ ];
147
+
148
+ /**
149
+ * This file is the one exclusion, and it has to be: it SPELLS the mistakes it
150
+ * forbids — in its probes, in the doc comment above, and in the `Icons.${…}`
151
+ * template that formats a finding. Nothing outside a test copies an example out of
152
+ * a test. The list is pinned to exactly one path in the first assertion below, so
153
+ * it can neither grow quietly nor become a silent no-op through a typo.
154
+ */
155
+ const EXCLUDED = [join(__dirname, 'icon-references.test.ts')];
156
+ const CHECKED = SCANNED.filter((file) => !EXCLUDED.includes(file));
157
+
158
+ describe('icon reference integrity', () => {
159
+ it('reads a plausible repo — neither list may be empty or truncated', () => {
160
+ // Without these floors a broken traversal or a broken extractor makes every
161
+ // assertion below pass by finding nothing at all.
162
+ expect(ICON_EXPORTS.size).toBeGreaterThan(200);
163
+ expect(CHECKED.length).toBeGreaterThan(300);
164
+ expect(CHECKED).toContain(join(SRC, 'tab-bar', 'types.ts'));
165
+ expect(CHECKED).toContain(join(REPO_ROOT, 'docs', 'tab-bar.mdx'));
166
+
167
+ // Exactly one file is exempt, and it really is in the scan — a misspelled path
168
+ // here would make the exemption a no-op and the suite fail on itself instead.
169
+ expect(EXCLUDED).toHaveLength(1);
170
+ expect(SCANNED).toContain(EXCLUDED[0]);
171
+ expect(CHECKED).not.toContain(EXCLUDED[0]);
172
+ });
173
+
174
+ it('collects every export shape src/icons uses, types included', () => {
175
+ // The suffixed component itself, the helpers, and the two TYPE exports that an
176
+ // earlier version of this check mistook for phantom references.
177
+ for (const name of [
178
+ 'Home_Stroke2_Corner0_Rounded',
179
+ 'PlusLarge_Stroke2_Corner0_Rounded',
180
+ 'sizes',
181
+ 'useCommonSVGProps',
182
+ 'createSinglePathSVG',
183
+ 'IconStyle',
184
+ 'Props',
185
+ ]) {
186
+ expect([...ICON_EXPORTS]).toContain(name);
187
+ }
188
+ // And nothing shortened is in there, which is the premise of the whole test.
189
+ expect(ICON_EXPORTS.has('Home')).toBe(false);
190
+ expect(ICON_EXPORTS.has('Icons')).toBe(false);
191
+ });
192
+
193
+ it('resolves the export/import directions of `as` correctly', () => {
194
+ // `export { A as B }` publishes B; `import { A as B }` reads A.
195
+ expect(exportedNames("export { TimesLarge_Stroke2_Corner0_Rounded as X } from './Times';")).toEqual(
196
+ ['X'],
197
+ );
198
+ expect(namedBindings('Check_Stroke2_Corner0_Rounded as CheckIcon', 'import')).toEqual([
199
+ 'Check_Stroke2_Corner0_Rounded',
200
+ ]);
201
+ });
202
+
203
+ it('flags the two mistakes that have actually been made', () => {
204
+ const probe = [
205
+ "import { Icons } from '@oxyhq/bloom/icons';",
206
+ 'const a = <Icons.Home />;',
207
+ "import { Bell, Home } from '@oxyhq/bloom/icons';",
208
+ " * A doc comment saying `<Icons.Lock size=\"sm\" />`, which is where four of these lived.",
209
+ ].join('\n');
210
+
211
+ expect(unresolvedIconRefs(probe, ICON_EXPORTS)).toEqual([
212
+ { line: 1, ref: "{ Icons } from '@oxyhq/bloom/icons'" },
213
+ { line: 2, ref: 'Icons.Home' },
214
+ { line: 3, ref: "{ Bell } from '@oxyhq/bloom/icons'" },
215
+ { line: 3, ref: "{ Home } from '@oxyhq/bloom/icons'" },
216
+ { line: 4, ref: 'Icons.Lock' },
217
+ ]);
218
+ });
219
+
220
+ it('leaves every correct form alone', () => {
221
+ const probe = [
222
+ "import * as Icons from '@oxyhq/bloom/icons';",
223
+ "import { Icons } from '@oxyhq/bloom';",
224
+ 'const a = <Icons.Home_Stroke2_Corner0_Rounded />;',
225
+ "import { Check_Stroke2_Corner0_Rounded as CheckIcon } from '../icons/Check';",
226
+ "import { type IconStyle, type Props as SVGIconProps } from '../icons/common';",
227
+ '| `Icons` | `export * as Icons` | keep namespace | `Icons.*` |',
228
+ "import { useState } from 'react';",
229
+ ].join('\n');
230
+
231
+ expect(unresolvedIconRefs(probe, ICON_EXPORTS)).toEqual([]);
232
+ });
233
+
234
+ it('every icon reference in src, docs, README and AGENTS resolves', () => {
235
+ const problems = CHECKED.flatMap((file) =>
236
+ unresolvedIconRefs(readFileSync(file, 'utf8'), ICON_EXPORTS).map(
237
+ ({ line, ref }) => `${relative(REPO_ROOT, file)}:${line} ${ref}`,
238
+ ),
239
+ );
240
+
241
+ expect(problems).toEqual([]);
242
+ });
243
+ });
@@ -0,0 +1,98 @@
1
+ import {
2
+ MAX_CACHED_ANIMATIONS,
3
+ getToastEnterAnimation,
4
+ getToastExitAnimation,
5
+ toastAnimationCacheSize,
6
+ } from '../toast/animations';
7
+ import type { ToastPosition } from '../toast/types';
8
+
9
+ const POSITIONS: ToastPosition[] = ['top-center', 'bottom-center', 'center'];
10
+
11
+ describe('toast layout animations', () => {
12
+ it('returns the same instance for the same enter shape', () => {
13
+ const first = getToastEnterAnimation('bottom-center');
14
+ expect(getToastEnterAnimation('bottom-center')).toBe(first);
15
+ });
16
+
17
+ it('returns a different enter instance per position', () => {
18
+ const instances = POSITIONS.map((position) =>
19
+ getToastEnterAnimation(position),
20
+ );
21
+ expect(new Set(instances).size).toBe(POSITIONS.length);
22
+ });
23
+
24
+ it('returns a different exit instance per position', () => {
25
+ const instances = POSITIONS.map((position) =>
26
+ getToastExitAnimation({
27
+ position,
28
+ isHiddenByLimit: false,
29
+ isSingle: true,
30
+ stackGap: 8,
31
+ }),
32
+ );
33
+ expect(new Set(instances).size).toBe(POSITIONS.length);
34
+ });
35
+
36
+ it('returns the same instance for the same exit shape', () => {
37
+ const shape = {
38
+ position: 'bottom-center' as const,
39
+ isHiddenByLimit: false,
40
+ isSingle: true,
41
+ stackGap: 8,
42
+ };
43
+ expect(getToastExitAnimation(shape)).toBe(getToastExitAnimation(shape));
44
+ });
45
+
46
+ it.each([
47
+ ['isHiddenByLimit', { isHiddenByLimit: true }],
48
+ ['isSingle', { isSingle: false }],
49
+ ['stackGap', { stackGap: 12 }],
50
+ ['position', { position: 'top-center' as const }],
51
+ ])('keys the exit cache on %s', (_label, override) => {
52
+ const base = {
53
+ position: 'bottom-center' as const,
54
+ isHiddenByLimit: false,
55
+ isSingle: true,
56
+ stackGap: 8,
57
+ };
58
+ expect(getToastExitAnimation({ ...base, ...override })).not.toBe(
59
+ getToastExitAnimation(base),
60
+ );
61
+ });
62
+
63
+ it('gives each cached instance its own definition object', () => {
64
+ // `Keyframe.parseDefinitions()` mutates the definitions it was built with
65
+ // (rewriting `from`/`to` into `0`/`100`), so two instances sharing one object
66
+ // would make the second throw. Distinct instances must not alias.
67
+ const first = getToastEnterAnimation('top-center');
68
+ const second = getToastEnterAnimation('bottom-center');
69
+ expect(first).not.toBe(second);
70
+ });
71
+
72
+ it('never grows past MAX_CACHED_ANIMATIONS, however many gaps are used', () => {
73
+ for (let stackGap = 0; stackGap < MAX_CACHED_ANIMATIONS * 4; stackGap++) {
74
+ getToastExitAnimation({
75
+ position: 'bottom-center',
76
+ isHiddenByLimit: false,
77
+ isSingle: false,
78
+ stackGap,
79
+ });
80
+ }
81
+ expect(toastAnimationCacheSize()).toBeLessThanOrEqual(
82
+ MAX_CACHED_ANIMATIONS,
83
+ );
84
+ });
85
+
86
+ it('still serves a shape that was evicted, by rebuilding it', () => {
87
+ const rebuilt = getToastExitAnimation({
88
+ position: 'bottom-center',
89
+ isHiddenByLimit: false,
90
+ isSingle: false,
91
+ stackGap: 0,
92
+ });
93
+ expect(rebuilt).toBeDefined();
94
+ expect(toastAnimationCacheSize()).toBeLessThanOrEqual(
95
+ MAX_CACHED_ANIMATIONS,
96
+ );
97
+ });
98
+ });
@@ -0,0 +1,131 @@
1
+ import React from 'react';
2
+
3
+ import { areToastsEqual } from '../toast/toast-comparator';
4
+ import { isToastAction, type ToastProps } from '../toast/types';
5
+
6
+ const baseToast = (overrides: Partial<ToastProps> = {}): ToastProps => ({
7
+ id: 'a',
8
+ index: 0,
9
+ title: 'Saved',
10
+ numberOfToasts: 1,
11
+ orderedToastIds: ['a'],
12
+ ...overrides,
13
+ });
14
+
15
+ describe('areToastsEqual', () => {
16
+ it('treats two structurally identical toasts as equal', () => {
17
+ expect(areToastsEqual(baseToast(), baseToast())).toBe(true);
18
+ });
19
+
20
+ it.each<[string, Partial<ToastProps>]>([
21
+ ['id', { id: 'b' }],
22
+ ['title', { title: 'Changed' }],
23
+ ['variant', { variant: 'error' }],
24
+ ['description', { description: 'details' }],
25
+ ['closeButton', { closeButton: true }],
26
+ ['invert', { invert: true }],
27
+ ['position', { position: 'top-center' }],
28
+ ['dismissible', { dismissible: false }],
29
+ ['duration', { duration: 10 }],
30
+ ['important', { important: true }],
31
+ ['richColors', { richColors: true }],
32
+ ['style', { style: { opacity: 0.5 } }],
33
+ ['styles', { styles: { title: { fontSize: 9 } } }],
34
+ ])('reports a change of %s', (_field, overrides) => {
35
+ expect(areToastsEqual(baseToast(), baseToast(overrides))).toBe(false);
36
+ });
37
+
38
+ it('compares icon and jsx by reference', () => {
39
+ const icon = React.createElement('Icon');
40
+ expect(
41
+ areToastsEqual(baseToast({ icon }), baseToast({ icon })),
42
+ ).toBe(true);
43
+ expect(
44
+ areToastsEqual(
45
+ baseToast({ icon }),
46
+ baseToast({ icon: React.createElement('Icon') }),
47
+ ),
48
+ ).toBe(false);
49
+ });
50
+
51
+ it('compares promiseOptions by reference', () => {
52
+ const promiseOptions = {
53
+ promise: Promise.resolve('ok'),
54
+ loading: 'Saving…',
55
+ error: 'Failed',
56
+ };
57
+ expect(
58
+ areToastsEqual(baseToast({ promiseOptions }), baseToast({ promiseOptions })),
59
+ ).toBe(true);
60
+ expect(
61
+ areToastsEqual(
62
+ baseToast({ promiseOptions }),
63
+ baseToast({
64
+ promiseOptions: { ...promiseOptions },
65
+ }),
66
+ ),
67
+ ).toBe(false);
68
+ });
69
+
70
+ it('compares actions by label, so a fresh onClick closure is not a change', () => {
71
+ expect(
72
+ areToastsEqual(
73
+ baseToast({ action: { label: 'Undo', onClick: () => {} } }),
74
+ baseToast({ action: { label: 'Undo', onClick: () => {} } }),
75
+ ),
76
+ ).toBe(true);
77
+
78
+ expect(
79
+ areToastsEqual(
80
+ baseToast({ action: { label: 'Undo', onClick: () => {} } }),
81
+ baseToast({ action: { label: 'Retry', onClick: () => {} } }),
82
+ ),
83
+ ).toBe(false);
84
+ });
85
+
86
+ it('compares a rendered action node by reference', () => {
87
+ const action = React.createElement('Button');
88
+ expect(areToastsEqual(baseToast({ action }), baseToast({ action }))).toBe(
89
+ true,
90
+ );
91
+ expect(
92
+ areToastsEqual(
93
+ baseToast({ action }),
94
+ baseToast({ action: React.createElement('Button') }),
95
+ ),
96
+ ).toBe(false);
97
+ });
98
+
99
+ it('applies the same rules to cancel', () => {
100
+ expect(
101
+ areToastsEqual(
102
+ baseToast({ cancel: { label: 'Dismiss', onClick: () => {} } }),
103
+ baseToast({ cancel: { label: 'Dismiss', onClick: () => {} } }),
104
+ ),
105
+ ).toBe(true);
106
+ expect(
107
+ areToastsEqual(
108
+ baseToast({ cancel: { label: 'Dismiss', onClick: () => {} } }),
109
+ baseToast({ cancel: { label: 'Close', onClick: () => {} } }),
110
+ ),
111
+ ).toBe(false);
112
+ });
113
+ });
114
+
115
+ describe('isToastAction', () => {
116
+ it('accepts a label + onClick pair', () => {
117
+ expect(isToastAction({ label: 'Undo', onClick: () => {} })).toBe(true);
118
+ });
119
+
120
+ it.each<[string, unknown]>([
121
+ ['undefined', undefined],
122
+ ['null', null],
123
+ ['a string', 'Undo'],
124
+ ['a React element', React.createElement('Button')],
125
+ ['a partial action', { label: 'Undo' }],
126
+ ['a non-string label', { label: 7, onClick: () => {} }],
127
+ ['a non-function onClick', { label: 'Undo', onClick: 'nope' }],
128
+ ])('rejects %s', (_label, value) => {
129
+ expect(isToastAction(value as React.ReactNode)).toBe(false);
130
+ });
131
+ });
@@ -0,0 +1,147 @@
1
+ /**
2
+ * The toast engine has exactly ONE platform switch — `TOAST_ENTER_DRIVER`, which
3
+ * mechanism plays the DEFAULT enter animation. Both halves are load-bearing, and
4
+ * each one broke the other platform when it was applied universally:
5
+ *
6
+ * web — a `Keyframe` on `entering` is frozen in place by reanimated's web
7
+ * layout-animation cleanup `duration * 5` later, so a second toast
8
+ * lands on top of the first.
9
+ * native — driving the enter imperatively stopped a `bottom-center` toast from
10
+ * painting at all.
11
+ *
12
+ * The invariant these tests protect: EXACTLY ONE of `entering` / `enterTranslateY`
13
+ * is ever set. Both would play the enter twice. Neither would leave the row with no
14
+ * enter animation and, on the imperative path, parked at `opacity: 0` one full
15
+ * `enterTranslateY` from its slot — which is exactly how the native regression
16
+ * presented.
17
+ */
18
+ import { FadeIn } from 'react-native-reanimated';
19
+
20
+ import {
21
+ TOAST_ENTER_DRIVER,
22
+ resolveToastEnterAnimation,
23
+ type ToastEnterDriver,
24
+ } from '../toast/animations';
25
+ import type { ToastPosition } from '../toast/types';
26
+
27
+ interface RNMock {
28
+ Platform: { OS: 'ios' | 'android' | 'web' | 'windows' | 'macos' };
29
+ }
30
+
31
+ const POSITIONS: ToastPosition[] = ['bottom-center', 'top-center', 'center'];
32
+ const DRIVERS: ToastEnterDriver[] = ['imperative', 'layoutAnimation'];
33
+
34
+ /** Re-evaluate the module against a given `Platform.OS`. */
35
+ const driverFor = (os: RNMock['Platform']['OS']): ToastEnterDriver => {
36
+ let driver: ToastEnterDriver | undefined;
37
+ jest.isolateModules(() => {
38
+ (require('react-native') as RNMock).Platform.OS = os;
39
+ driver = (require('../toast/animations') as { TOAST_ENTER_DRIVER: ToastEnterDriver })
40
+ .TOAST_ENTER_DRIVER;
41
+ });
42
+ if (!driver) {
43
+ throw new Error('module did not evaluate');
44
+ }
45
+ return driver;
46
+ };
47
+
48
+ describe('TOAST_ENTER_DRIVER', () => {
49
+ afterEach(() => {
50
+ (require('react-native') as RNMock).Platform.OS = 'ios';
51
+ });
52
+
53
+ it('is imperative on web only', () => {
54
+ expect(driverFor('web')).toBe('imperative');
55
+ expect(driverFor('ios')).toBe('layoutAnimation');
56
+ expect(driverFor('android')).toBe('layoutAnimation');
57
+ });
58
+
59
+ it('is a real value under the suite’s own platform', () => {
60
+ expect(DRIVERS).toContain(TOAST_ENTER_DRIVER);
61
+ });
62
+ });
63
+
64
+ describe('resolveToastEnterAnimation', () => {
65
+ it.each(DRIVERS)(
66
+ 'sets exactly one of entering / enterTranslateY (%s), at every position',
67
+ (driver) => {
68
+ for (const position of POSITIONS) {
69
+ const resolved = resolveToastEnterAnimation({
70
+ position,
71
+ enterOverride: undefined,
72
+ driver,
73
+ });
74
+ const set = [resolved.entering, resolved.enterTranslateY].filter(
75
+ (value) => value !== undefined,
76
+ );
77
+ expect({ driver, position, count: set.length }).toEqual({
78
+ driver,
79
+ position,
80
+ count: 1,
81
+ });
82
+ }
83
+ },
84
+ );
85
+
86
+ it('drives the default enter imperatively, never through `entering`, on the imperative driver', () => {
87
+ const resolved = resolveToastEnterAnimation({
88
+ position: 'bottom-center',
89
+ enterOverride: undefined,
90
+ driver: 'imperative',
91
+ });
92
+ expect(resolved.entering).toBeUndefined();
93
+ expect(resolved.enterTranslateY).toBe(50);
94
+ });
95
+
96
+ it('travels the other way at top-center', () => {
97
+ expect(
98
+ resolveToastEnterAnimation({
99
+ position: 'top-center',
100
+ enterOverride: undefined,
101
+ driver: 'imperative',
102
+ }).enterTranslateY,
103
+ ).toBe(-20);
104
+ });
105
+
106
+ it('drives the default enter through `entering`, never imperatively, on the layout driver', () => {
107
+ const resolved = resolveToastEnterAnimation({
108
+ position: 'bottom-center',
109
+ enterOverride: undefined,
110
+ driver: 'layoutAnimation',
111
+ });
112
+ expect(resolved.entering).toBeDefined();
113
+ expect(resolved.enterTranslateY).toBeUndefined();
114
+ });
115
+
116
+ it.each(DRIVERS)(
117
+ 'hands a consumer override to `entering` and drives nothing imperatively (%s)',
118
+ (driver) => {
119
+ const resolved = resolveToastEnterAnimation({
120
+ position: 'bottom-center',
121
+ enterOverride: FadeIn,
122
+ driver,
123
+ });
124
+ expect(resolved.entering).toBe(FadeIn);
125
+ expect(resolved.enterTranslateY).toBeUndefined();
126
+ },
127
+ );
128
+
129
+ it.each(DRIVERS)(
130
+ "treats 'default' as no override at all (%s)",
131
+ (driver) => {
132
+ expect(
133
+ resolveToastEnterAnimation({
134
+ position: 'bottom-center',
135
+ enterOverride: 'default',
136
+ driver,
137
+ }),
138
+ ).toEqual(
139
+ resolveToastEnterAnimation({
140
+ position: 'bottom-center',
141
+ enterOverride: undefined,
142
+ driver,
143
+ }),
144
+ );
145
+ },
146
+ );
147
+ });