@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.
- package/NOTICE +89 -0
- package/README.md +12 -7
- package/lib/commonjs/avatar-group/AvatarGroup.web.js +2 -1
- package/lib/commonjs/avatar-group/AvatarGroup.web.js.map +1 -1
- package/lib/commonjs/bottom-sheet/index.web.js +2 -1
- package/lib/commonjs/bottom-sheet/index.web.js.map +1 -1
- package/lib/commonjs/context-menu/index.web.js +3 -2
- package/lib/commonjs/context-menu/index.web.js.map +1 -1
- package/lib/commonjs/dialog/Dialog.web.js +4 -3
- package/lib/commonjs/dialog/Dialog.web.js.map +1 -1
- package/lib/commonjs/frosted-icon-button/shared.js +1 -1
- package/lib/commonjs/index.js +90 -83
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/index.web.js +116 -109
- package/lib/commonjs/index.web.js.map +1 -1
- package/lib/commonjs/menu/index.web.js +2 -1
- package/lib/commonjs/menu/index.web.js.map +1 -1
- package/lib/commonjs/popover/index.web.js +3 -2
- package/lib/commonjs/popover/index.web.js.map +1 -1
- package/lib/commonjs/portal/index.js +4 -1
- package/lib/commonjs/portal/index.js.map +1 -1
- package/lib/commonjs/progressive-blur/index.js +79 -0
- package/lib/commonjs/progressive-blur/index.js.map +1 -0
- package/lib/commonjs/progressive-blur/index.web.js +67 -0
- package/lib/commonjs/progressive-blur/index.web.js.map +1 -0
- package/lib/commonjs/progressive-blur/shared.js +66 -0
- package/lib/commonjs/progressive-blur/shared.js.map +1 -0
- package/lib/commonjs/progressive-blur/types.js +6 -0
- package/lib/commonjs/progressive-blur/types.js.map +1 -0
- package/lib/commonjs/select/index.web.js +2 -1
- package/lib/commonjs/select/index.web.js.map +1 -1
- package/lib/commonjs/styles/web-view-style.js +26 -0
- package/lib/commonjs/styles/web-view-style.js.map +1 -0
- package/lib/commonjs/tab-bar/TabBarBase.js +415 -0
- package/lib/commonjs/tab-bar/TabBarBase.js.map +1 -0
- package/lib/commonjs/tab-bar/expo-router/RouterTabBar.js +83 -0
- package/lib/commonjs/tab-bar/expo-router/RouterTabBar.js.map +1 -0
- package/lib/commonjs/tab-bar/expo-router/fading-tab-screen.js +119 -0
- package/lib/commonjs/tab-bar/expo-router/fading-tab-screen.js.map +1 -0
- package/lib/commonjs/tab-bar/expo-router/index.js +26 -0
- package/lib/commonjs/tab-bar/expo-router/index.js.map +1 -0
- package/lib/commonjs/tab-bar/glyph.js +43 -0
- package/lib/commonjs/tab-bar/glyph.js.map +1 -0
- package/lib/commonjs/tab-bar/glyph.native.js +55 -0
- package/lib/commonjs/tab-bar/glyph.native.js.map +1 -0
- package/lib/commonjs/tab-bar/index.js +65 -0
- package/lib/commonjs/tab-bar/index.js.map +1 -0
- package/lib/commonjs/tab-bar/index.web.js +67 -0
- package/lib/commonjs/tab-bar/index.web.js.map +1 -0
- package/lib/commonjs/tab-bar/minimize-context.js +127 -0
- package/lib/commonjs/tab-bar/minimize-context.js.map +1 -0
- package/lib/commonjs/tab-bar/shared.js +139 -0
- package/lib/commonjs/tab-bar/shared.js.map +1 -0
- package/lib/commonjs/tab-bar/surface-solid.js +43 -0
- package/lib/commonjs/tab-bar/surface-solid.js.map +1 -0
- package/lib/commonjs/tab-bar/surface.js +13 -0
- package/lib/commonjs/tab-bar/surface.js.map +1 -0
- package/lib/commonjs/tab-bar/surface.native.js +113 -0
- package/lib/commonjs/tab-bar/surface.native.js.map +1 -0
- package/lib/commonjs/tab-bar/surface.web.js +59 -0
- package/lib/commonjs/tab-bar/surface.web.js.map +1 -0
- package/lib/commonjs/tab-bar/types.js +6 -0
- package/lib/commonjs/tab-bar/types.js.map +1 -0
- package/lib/commonjs/toast/Positioner.js +117 -0
- package/lib/commonjs/toast/Positioner.js.map +1 -0
- package/lib/commonjs/toast/ToastContent.js +301 -0
- package/lib/commonjs/toast/ToastContent.js.map +1 -0
- package/lib/commonjs/toast/ToastHost.js +69 -0
- package/lib/commonjs/toast/ToastHost.js.map +1 -0
- package/lib/commonjs/toast/ToastHost.native.js +44 -0
- package/lib/commonjs/toast/ToastHost.native.js.map +1 -0
- package/lib/commonjs/toast/ToastIcon.js +57 -0
- package/lib/commonjs/toast/ToastIcon.js.map +1 -0
- package/lib/commonjs/toast/ToastRow.js +411 -0
- package/lib/commonjs/toast/ToastRow.js.map +1 -0
- package/lib/commonjs/toast/ToastSwipeHandler.js +189 -0
- package/lib/commonjs/toast/ToastSwipeHandler.js.map +1 -0
- package/lib/commonjs/toast/Toaster.js +205 -0
- package/lib/commonjs/toast/Toaster.js.map +1 -0
- package/lib/commonjs/toast/animations.js +274 -0
- package/lib/commonjs/toast/animations.js.map +1 -0
- package/lib/commonjs/toast/constants.js +56 -0
- package/lib/commonjs/toast/constants.js.map +1 -0
- package/lib/commonjs/toast/context.js +42 -0
- package/lib/commonjs/toast/context.js.map +1 -0
- package/lib/commonjs/toast/index.js +32 -126
- package/lib/commonjs/toast/index.js.map +1 -1
- package/lib/commonjs/toast/position-utils.js +115 -0
- package/lib/commonjs/toast/position-utils.js.map +1 -0
- package/lib/commonjs/toast/positioner-utils.js +141 -0
- package/lib/commonjs/toast/positioner-utils.js.map +1 -0
- package/lib/commonjs/toast/toast-comparator.js +28 -0
- package/lib/commonjs/toast/toast-comparator.js.map +1 -0
- package/lib/commonjs/toast/toast-fns.js +90 -0
- package/lib/commonjs/toast/toast-fns.js.map +1 -0
- package/lib/commonjs/toast/toast-store.js +352 -0
- package/lib/commonjs/toast/toast-store.js.map +1 -0
- package/lib/commonjs/toast/toast-timers.js +110 -0
- package/lib/commonjs/toast/toast-timers.js.map +1 -0
- package/lib/commonjs/toast/types.js +42 -0
- package/lib/commonjs/toast/types.js.map +1 -1
- package/lib/commonjs/toast/use-animated-target.js +57 -0
- package/lib/commonjs/toast/use-animated-target.js.map +1 -0
- package/lib/commonjs/toast/use-app-state.js +76 -0
- package/lib/commonjs/toast/use-app-state.js.map +1 -0
- package/lib/commonjs/toast/use-toast-colors.js +114 -0
- package/lib/commonjs/toast/use-toast-colors.js.map +1 -0
- package/lib/commonjs/toast/use-toast-position.js +40 -0
- package/lib/commonjs/toast/use-toast-position.js.map +1 -0
- package/lib/commonjs/tooltip/index.web.js +2 -1
- package/lib/commonjs/tooltip/index.web.js.map +1 -1
- package/lib/commonjs/zoomable-image-gallery/ZoomableImageGallery.js +20 -8
- package/lib/commonjs/zoomable-image-gallery/ZoomableImageGallery.js.map +1 -1
- package/lib/module/avatar-group/AvatarGroup.web.js +2 -1
- package/lib/module/avatar-group/AvatarGroup.web.js.map +1 -1
- package/lib/module/bottom-sheet/index.web.js +2 -1
- package/lib/module/bottom-sheet/index.web.js.map +1 -1
- package/lib/module/context-menu/index.web.js +3 -2
- package/lib/module/context-menu/index.web.js.map +1 -1
- package/lib/module/dialog/Dialog.web.js +4 -3
- package/lib/module/dialog/Dialog.web.js.map +1 -1
- package/lib/module/frosted-icon-button/shared.js +1 -1
- package/lib/module/index.js +3 -2
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +3 -2
- package/lib/module/index.web.js.map +1 -1
- package/lib/module/menu/index.web.js +2 -1
- package/lib/module/menu/index.web.js.map +1 -1
- package/lib/module/popover/index.web.js +3 -2
- package/lib/module/popover/index.web.js.map +1 -1
- package/lib/module/portal/index.js +4 -1
- package/lib/module/portal/index.js.map +1 -1
- package/lib/module/progressive-blur/index.js +74 -0
- package/lib/module/progressive-blur/index.js.map +1 -0
- package/lib/module/progressive-blur/index.web.js +62 -0
- package/lib/module/progressive-blur/index.web.js.map +1 -0
- package/lib/module/progressive-blur/shared.js +60 -0
- package/lib/module/progressive-blur/shared.js.map +1 -0
- package/lib/module/progressive-blur/types.js +4 -0
- package/lib/module/progressive-blur/types.js.map +1 -0
- package/lib/module/select/index.web.js +2 -1
- package/lib/module/select/index.web.js.map +1 -1
- package/lib/module/styles/web-view-style.js +22 -0
- package/lib/module/styles/web-view-style.js.map +1 -0
- package/lib/module/tab-bar/TabBarBase.js +408 -0
- package/lib/module/tab-bar/TabBarBase.js.map +1 -0
- package/lib/module/tab-bar/expo-router/RouterTabBar.js +78 -0
- package/lib/module/tab-bar/expo-router/RouterTabBar.js.map +1 -0
- package/lib/module/tab-bar/expo-router/fading-tab-screen.js +113 -0
- package/lib/module/tab-bar/expo-router/fading-tab-screen.js.map +1 -0
- package/lib/module/tab-bar/expo-router/index.js +15 -0
- package/lib/module/tab-bar/expo-router/index.js.map +1 -0
- package/lib/module/tab-bar/glyph.js +38 -0
- package/lib/module/tab-bar/glyph.js.map +1 -0
- package/lib/module/tab-bar/glyph.native.js +50 -0
- package/lib/module/tab-bar/glyph.native.js.map +1 -0
- package/lib/module/tab-bar/index.js +24 -0
- package/lib/module/tab-bar/index.js.map +1 -0
- package/lib/module/tab-bar/index.web.js +26 -0
- package/lib/module/tab-bar/index.web.js.map +1 -0
- package/lib/module/tab-bar/minimize-context.js +118 -0
- package/lib/module/tab-bar/minimize-context.js.map +1 -0
- package/lib/module/tab-bar/shared.js +132 -0
- package/lib/module/tab-bar/shared.js.map +1 -0
- package/lib/module/tab-bar/surface-solid.js +37 -0
- package/lib/module/tab-bar/surface-solid.js.map +1 -0
- package/lib/module/tab-bar/surface.js +31 -0
- package/lib/module/tab-bar/surface.js.map +1 -0
- package/lib/module/tab-bar/surface.native.js +109 -0
- package/lib/module/tab-bar/surface.native.js.map +1 -0
- package/lib/module/tab-bar/surface.web.js +53 -0
- package/lib/module/tab-bar/surface.web.js.map +1 -0
- package/lib/module/tab-bar/types.js +4 -0
- package/lib/module/tab-bar/types.js.map +1 -0
- package/lib/module/toast/Positioner.js +110 -0
- package/lib/module/toast/Positioner.js.map +1 -0
- package/lib/module/toast/ToastContent.js +295 -0
- package/lib/module/toast/ToastContent.js.map +1 -0
- package/lib/module/toast/ToastHost.js +63 -0
- package/lib/module/toast/ToastHost.js.map +1 -0
- package/lib/module/toast/ToastHost.native.js +38 -0
- package/lib/module/toast/ToastHost.native.js.map +1 -0
- package/lib/module/toast/ToastIcon.js +52 -0
- package/lib/module/toast/ToastIcon.js.map +1 -0
- package/lib/module/toast/ToastRow.js +407 -0
- package/lib/module/toast/ToastRow.js.map +1 -0
- package/lib/module/toast/ToastSwipeHandler.js +182 -0
- package/lib/module/toast/ToastSwipeHandler.js.map +1 -0
- package/lib/module/toast/Toaster.js +198 -0
- package/lib/module/toast/Toaster.js.map +1 -0
- package/lib/module/toast/animations.js +261 -0
- package/lib/module/toast/animations.js.map +1 -0
- package/lib/module/toast/constants.js +52 -0
- package/lib/module/toast/constants.js.map +1 -0
- package/lib/module/toast/context.js +34 -0
- package/lib/module/toast/context.js.map +1 -0
- package/lib/module/toast/index.js +27 -103
- package/lib/module/toast/index.js.map +1 -1
- package/lib/module/toast/position-utils.js +107 -0
- package/lib/module/toast/position-utils.js.map +1 -0
- package/lib/module/toast/positioner-utils.js +134 -0
- package/lib/module/toast/positioner-utils.js.map +1 -0
- package/lib/module/toast/toast-comparator.js +22 -0
- package/lib/module/toast/toast-comparator.js.map +1 -0
- package/lib/module/toast/toast-fns.js +85 -0
- package/lib/module/toast/toast-fns.js.map +1 -0
- package/lib/module/toast/toast-store.js +346 -0
- package/lib/module/toast/toast-store.js.map +1 -0
- package/lib/module/toast/toast-timers.js +104 -0
- package/lib/module/toast/toast-timers.js.map +1 -0
- package/lib/module/toast/types.js +38 -0
- package/lib/module/toast/types.js.map +1 -1
- package/lib/module/toast/use-animated-target.js +52 -0
- package/lib/module/toast/use-animated-target.js.map +1 -0
- package/lib/module/toast/use-app-state.js +70 -0
- package/lib/module/toast/use-app-state.js.map +1 -0
- package/lib/module/toast/use-toast-colors.js +109 -0
- package/lib/module/toast/use-toast-colors.js.map +1 -0
- package/lib/module/toast/use-toast-position.js +35 -0
- package/lib/module/toast/use-toast-position.js.map +1 -0
- package/lib/module/tooltip/index.web.js +2 -1
- package/lib/module/tooltip/index.web.js.map +1 -1
- package/lib/module/zoomable-image-gallery/ZoomableImageGallery.js +20 -8
- package/lib/module/zoomable-image-gallery/ZoomableImageGallery.js.map +1 -1
- package/lib/typescript/commonjs/avatar-group/AvatarGroup.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/benefit-list/types.d.ts +2 -1
- package/lib/typescript/commonjs/benefit-list/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/bottom-sheet/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/context-menu/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/Dialog.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/fab/types.d.ts +4 -2
- package/lib/typescript/commonjs/fab/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/frosted-icon-button/shared.d.ts +1 -1
- package/lib/typescript/commonjs/frosted-icon-button/types.d.ts +2 -1
- package/lib/typescript/commonjs/frosted-icon-button/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +2 -1
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.web.d.ts +2 -1
- package/lib/typescript/commonjs/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/menu/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/popover/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/portal/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/progressive-blur/index.d.ts +23 -0
- package/lib/typescript/commonjs/progressive-blur/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/progressive-blur/index.web.d.ts +30 -0
- package/lib/typescript/commonjs/progressive-blur/index.web.d.ts.map +1 -0
- package/lib/typescript/commonjs/progressive-blur/shared.d.ts +35 -0
- package/lib/typescript/commonjs/progressive-blur/shared.d.ts.map +1 -0
- package/lib/typescript/commonjs/progressive-blur/types.d.ts +21 -0
- package/lib/typescript/commonjs/progressive-blur/types.d.ts.map +1 -0
- package/lib/typescript/commonjs/select/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/styles/web-view-style.d.ts +21 -0
- package/lib/typescript/commonjs/styles/web-view-style.d.ts.map +1 -0
- package/lib/typescript/commonjs/tab-bar/TabBarBase.d.ts +36 -0
- package/lib/typescript/commonjs/tab-bar/TabBarBase.d.ts.map +1 -0
- package/lib/typescript/commonjs/tab-bar/expo-router/RouterTabBar.d.ts +59 -0
- package/lib/typescript/commonjs/tab-bar/expo-router/RouterTabBar.d.ts.map +1 -0
- package/lib/typescript/commonjs/tab-bar/expo-router/fading-tab-screen.d.ts +11 -0
- package/lib/typescript/commonjs/tab-bar/expo-router/fading-tab-screen.d.ts.map +1 -0
- package/lib/typescript/commonjs/tab-bar/expo-router/index.d.ts +14 -0
- package/lib/typescript/commonjs/tab-bar/expo-router/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/tab-bar/glyph.d.ts +6 -0
- package/lib/typescript/commonjs/tab-bar/glyph.d.ts.map +1 -0
- package/lib/typescript/commonjs/tab-bar/glyph.native.d.ts +6 -0
- package/lib/typescript/commonjs/tab-bar/glyph.native.d.ts.map +1 -0
- package/lib/typescript/commonjs/tab-bar/index.d.ts +12 -0
- package/lib/typescript/commonjs/tab-bar/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/tab-bar/index.web.d.ts +12 -0
- package/lib/typescript/commonjs/tab-bar/index.web.d.ts.map +1 -0
- package/lib/typescript/commonjs/tab-bar/minimize-context.d.ts +51 -0
- package/lib/typescript/commonjs/tab-bar/minimize-context.d.ts.map +1 -0
- package/lib/typescript/commonjs/tab-bar/shared.d.ts +93 -0
- package/lib/typescript/commonjs/tab-bar/shared.d.ts.map +1 -0
- package/lib/typescript/commonjs/tab-bar/surface-solid.d.ts +6 -0
- package/lib/typescript/commonjs/tab-bar/surface-solid.d.ts.map +1 -0
- package/lib/typescript/commonjs/tab-bar/surface.d.ts +29 -0
- package/lib/typescript/commonjs/tab-bar/surface.d.ts.map +1 -0
- package/lib/typescript/commonjs/tab-bar/surface.native.d.ts +6 -0
- package/lib/typescript/commonjs/tab-bar/surface.native.d.ts.map +1 -0
- package/lib/typescript/commonjs/tab-bar/surface.web.d.ts +6 -0
- package/lib/typescript/commonjs/tab-bar/surface.web.d.ts.map +1 -0
- package/lib/typescript/commonjs/tab-bar/types.d.ts +88 -0
- package/lib/typescript/commonjs/tab-bar/types.d.ts.map +1 -0
- package/lib/typescript/commonjs/toast/Positioner.d.ts +21 -0
- package/lib/typescript/commonjs/toast/Positioner.d.ts.map +1 -0
- package/lib/typescript/commonjs/toast/ToastContent.d.ts +14 -0
- package/lib/typescript/commonjs/toast/ToastContent.d.ts.map +1 -0
- package/lib/typescript/commonjs/toast/ToastHost.d.ts +6 -0
- package/lib/typescript/commonjs/toast/ToastHost.d.ts.map +1 -0
- package/lib/typescript/commonjs/toast/ToastHost.native.d.ts +6 -0
- package/lib/typescript/commonjs/toast/ToastHost.native.d.ts.map +1 -0
- package/lib/typescript/commonjs/toast/ToastIcon.d.ts +9 -0
- package/lib/typescript/commonjs/toast/ToastIcon.d.ts.map +1 -0
- package/lib/typescript/commonjs/toast/ToastRow.d.ts +80 -0
- package/lib/typescript/commonjs/toast/ToastRow.d.ts.map +1 -0
- package/lib/typescript/commonjs/toast/ToastSwipeHandler.d.ts +30 -0
- package/lib/typescript/commonjs/toast/ToastSwipeHandler.d.ts.map +1 -0
- package/lib/typescript/commonjs/toast/Toaster.d.ts +19 -0
- package/lib/typescript/commonjs/toast/Toaster.d.ts.map +1 -0
- package/lib/typescript/commonjs/toast/animations.d.ts +62 -0
- package/lib/typescript/commonjs/toast/animations.d.ts.map +1 -0
- package/lib/typescript/commonjs/toast/constants.d.ts +39 -0
- package/lib/typescript/commonjs/toast/constants.d.ts.map +1 -0
- package/lib/typescript/commonjs/toast/context.d.ts +19 -0
- package/lib/typescript/commonjs/toast/context.d.ts.map +1 -0
- package/lib/typescript/commonjs/toast/index.d.ts +23 -76
- package/lib/typescript/commonjs/toast/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/toast/position-utils.d.ts +30 -0
- package/lib/typescript/commonjs/toast/position-utils.d.ts.map +1 -0
- package/lib/typescript/commonjs/toast/positioner-utils.d.ts +72 -0
- package/lib/typescript/commonjs/toast/positioner-utils.d.ts.map +1 -0
- package/lib/typescript/commonjs/toast/toast-comparator.d.ts +12 -0
- package/lib/typescript/commonjs/toast/toast-comparator.d.ts.map +1 -0
- package/lib/typescript/commonjs/toast/toast-fns.d.ts +3 -0
- package/lib/typescript/commonjs/toast/toast-fns.d.ts.map +1 -0
- package/lib/typescript/commonjs/toast/toast-store.d.ts +52 -0
- package/lib/typescript/commonjs/toast/toast-store.d.ts.map +1 -0
- package/lib/typescript/commonjs/toast/toast-timers.d.ts +24 -0
- package/lib/typescript/commonjs/toast/toast-timers.d.ts.map +1 -0
- package/lib/typescript/commonjs/toast/types.d.ts +222 -5
- package/lib/typescript/commonjs/toast/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/toast/use-animated-target.d.ts +7 -0
- package/lib/typescript/commonjs/toast/use-animated-target.d.ts.map +1 -0
- package/lib/typescript/commonjs/toast/use-app-state.d.ts +18 -0
- package/lib/typescript/commonjs/toast/use-app-state.d.ts.map +1 -0
- package/lib/typescript/commonjs/toast/use-toast-colors.d.ts +22 -0
- package/lib/typescript/commonjs/toast/use-toast-colors.d.ts.map +1 -0
- package/lib/typescript/commonjs/toast/use-toast-position.d.ts +37 -0
- package/lib/typescript/commonjs/toast/use-toast-position.d.ts.map +1 -0
- package/lib/typescript/commonjs/tooltip/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/zoomable-image-gallery/ZoomableImageGallery.d.ts.map +1 -1
- package/lib/typescript/module/avatar-group/AvatarGroup.web.d.ts.map +1 -1
- package/lib/typescript/module/benefit-list/types.d.ts +2 -1
- package/lib/typescript/module/benefit-list/types.d.ts.map +1 -1
- package/lib/typescript/module/bottom-sheet/index.web.d.ts.map +1 -1
- package/lib/typescript/module/context-menu/index.web.d.ts.map +1 -1
- package/lib/typescript/module/dialog/Dialog.web.d.ts.map +1 -1
- package/lib/typescript/module/fab/types.d.ts +4 -2
- package/lib/typescript/module/fab/types.d.ts.map +1 -1
- package/lib/typescript/module/frosted-icon-button/shared.d.ts +1 -1
- package/lib/typescript/module/frosted-icon-button/types.d.ts +2 -1
- package/lib/typescript/module/frosted-icon-button/types.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +2 -1
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/index.web.d.ts +2 -1
- package/lib/typescript/module/index.web.d.ts.map +1 -1
- package/lib/typescript/module/menu/index.web.d.ts.map +1 -1
- package/lib/typescript/module/popover/index.web.d.ts.map +1 -1
- package/lib/typescript/module/portal/index.d.ts.map +1 -1
- package/lib/typescript/module/progressive-blur/index.d.ts +23 -0
- package/lib/typescript/module/progressive-blur/index.d.ts.map +1 -0
- package/lib/typescript/module/progressive-blur/index.web.d.ts +30 -0
- package/lib/typescript/module/progressive-blur/index.web.d.ts.map +1 -0
- package/lib/typescript/module/progressive-blur/shared.d.ts +35 -0
- package/lib/typescript/module/progressive-blur/shared.d.ts.map +1 -0
- package/lib/typescript/module/progressive-blur/types.d.ts +21 -0
- package/lib/typescript/module/progressive-blur/types.d.ts.map +1 -0
- package/lib/typescript/module/select/index.web.d.ts.map +1 -1
- package/lib/typescript/module/styles/web-view-style.d.ts +21 -0
- package/lib/typescript/module/styles/web-view-style.d.ts.map +1 -0
- package/lib/typescript/module/tab-bar/TabBarBase.d.ts +36 -0
- package/lib/typescript/module/tab-bar/TabBarBase.d.ts.map +1 -0
- package/lib/typescript/module/tab-bar/expo-router/RouterTabBar.d.ts +59 -0
- package/lib/typescript/module/tab-bar/expo-router/RouterTabBar.d.ts.map +1 -0
- package/lib/typescript/module/tab-bar/expo-router/fading-tab-screen.d.ts +11 -0
- package/lib/typescript/module/tab-bar/expo-router/fading-tab-screen.d.ts.map +1 -0
- package/lib/typescript/module/tab-bar/expo-router/index.d.ts +14 -0
- package/lib/typescript/module/tab-bar/expo-router/index.d.ts.map +1 -0
- package/lib/typescript/module/tab-bar/glyph.d.ts +6 -0
- package/lib/typescript/module/tab-bar/glyph.d.ts.map +1 -0
- package/lib/typescript/module/tab-bar/glyph.native.d.ts +6 -0
- package/lib/typescript/module/tab-bar/glyph.native.d.ts.map +1 -0
- package/lib/typescript/module/tab-bar/index.d.ts +12 -0
- package/lib/typescript/module/tab-bar/index.d.ts.map +1 -0
- package/lib/typescript/module/tab-bar/index.web.d.ts +12 -0
- package/lib/typescript/module/tab-bar/index.web.d.ts.map +1 -0
- package/lib/typescript/module/tab-bar/minimize-context.d.ts +51 -0
- package/lib/typescript/module/tab-bar/minimize-context.d.ts.map +1 -0
- package/lib/typescript/module/tab-bar/shared.d.ts +93 -0
- package/lib/typescript/module/tab-bar/shared.d.ts.map +1 -0
- package/lib/typescript/module/tab-bar/surface-solid.d.ts +6 -0
- package/lib/typescript/module/tab-bar/surface-solid.d.ts.map +1 -0
- package/lib/typescript/module/tab-bar/surface.d.ts +29 -0
- package/lib/typescript/module/tab-bar/surface.d.ts.map +1 -0
- package/lib/typescript/module/tab-bar/surface.native.d.ts +6 -0
- package/lib/typescript/module/tab-bar/surface.native.d.ts.map +1 -0
- package/lib/typescript/module/tab-bar/surface.web.d.ts +6 -0
- package/lib/typescript/module/tab-bar/surface.web.d.ts.map +1 -0
- package/lib/typescript/module/tab-bar/types.d.ts +88 -0
- package/lib/typescript/module/tab-bar/types.d.ts.map +1 -0
- package/lib/typescript/module/toast/Positioner.d.ts +21 -0
- package/lib/typescript/module/toast/Positioner.d.ts.map +1 -0
- package/lib/typescript/module/toast/ToastContent.d.ts +14 -0
- package/lib/typescript/module/toast/ToastContent.d.ts.map +1 -0
- package/lib/typescript/module/toast/ToastHost.d.ts +6 -0
- package/lib/typescript/module/toast/ToastHost.d.ts.map +1 -0
- package/lib/typescript/module/toast/ToastHost.native.d.ts +6 -0
- package/lib/typescript/module/toast/ToastHost.native.d.ts.map +1 -0
- package/lib/typescript/module/toast/ToastIcon.d.ts +9 -0
- package/lib/typescript/module/toast/ToastIcon.d.ts.map +1 -0
- package/lib/typescript/module/toast/ToastRow.d.ts +80 -0
- package/lib/typescript/module/toast/ToastRow.d.ts.map +1 -0
- package/lib/typescript/module/toast/ToastSwipeHandler.d.ts +30 -0
- package/lib/typescript/module/toast/ToastSwipeHandler.d.ts.map +1 -0
- package/lib/typescript/module/toast/Toaster.d.ts +19 -0
- package/lib/typescript/module/toast/Toaster.d.ts.map +1 -0
- package/lib/typescript/module/toast/animations.d.ts +62 -0
- package/lib/typescript/module/toast/animations.d.ts.map +1 -0
- package/lib/typescript/module/toast/constants.d.ts +39 -0
- package/lib/typescript/module/toast/constants.d.ts.map +1 -0
- package/lib/typescript/module/toast/context.d.ts +19 -0
- package/lib/typescript/module/toast/context.d.ts.map +1 -0
- package/lib/typescript/module/toast/index.d.ts +23 -76
- package/lib/typescript/module/toast/index.d.ts.map +1 -1
- package/lib/typescript/module/toast/position-utils.d.ts +30 -0
- package/lib/typescript/module/toast/position-utils.d.ts.map +1 -0
- package/lib/typescript/module/toast/positioner-utils.d.ts +72 -0
- package/lib/typescript/module/toast/positioner-utils.d.ts.map +1 -0
- package/lib/typescript/module/toast/toast-comparator.d.ts +12 -0
- package/lib/typescript/module/toast/toast-comparator.d.ts.map +1 -0
- package/lib/typescript/module/toast/toast-fns.d.ts +3 -0
- package/lib/typescript/module/toast/toast-fns.d.ts.map +1 -0
- package/lib/typescript/module/toast/toast-store.d.ts +52 -0
- package/lib/typescript/module/toast/toast-store.d.ts.map +1 -0
- package/lib/typescript/module/toast/toast-timers.d.ts +24 -0
- package/lib/typescript/module/toast/toast-timers.d.ts.map +1 -0
- package/lib/typescript/module/toast/types.d.ts +222 -5
- package/lib/typescript/module/toast/types.d.ts.map +1 -1
- package/lib/typescript/module/toast/use-animated-target.d.ts +7 -0
- package/lib/typescript/module/toast/use-animated-target.d.ts.map +1 -0
- package/lib/typescript/module/toast/use-app-state.d.ts +18 -0
- package/lib/typescript/module/toast/use-app-state.d.ts.map +1 -0
- package/lib/typescript/module/toast/use-toast-colors.d.ts +22 -0
- package/lib/typescript/module/toast/use-toast-colors.d.ts.map +1 -0
- package/lib/typescript/module/toast/use-toast-position.d.ts +37 -0
- package/lib/typescript/module/toast/use-toast-position.d.ts.map +1 -0
- package/lib/typescript/module/tooltip/index.web.d.ts.map +1 -1
- package/lib/typescript/module/zoomable-image-gallery/ZoomableImageGallery.d.ts.map +1 -1
- package/package.json +58 -26
- package/src/__tests__/TabBar.test.tsx +342 -0
- package/src/__tests__/TabBarGlassFallback.test.tsx +234 -0
- package/src/__tests__/TabBarReanimatedDeps.test.ts +130 -0
- package/src/__tests__/TabBarWebFork.test.ts +243 -0
- package/src/__tests__/ToastContent.test.tsx +192 -0
- package/src/__tests__/ToastHostWebFork.test.ts +155 -0
- package/src/__tests__/Toaster.test.tsx +527 -0
- package/src/__tests__/animated-style-deps.test.ts +156 -0
- package/src/__tests__/icon-references.test.ts +243 -0
- package/src/__tests__/toast-animations.test.ts +98 -0
- package/src/__tests__/toast-comparator.test.ts +131 -0
- package/src/__tests__/toast-enter-driver.test.ts +147 -0
- package/src/__tests__/toast-fns.test.ts +240 -0
- package/src/__tests__/toast-position-utils.test.ts +259 -0
- package/src/__tests__/toast-positioner-utils.test.ts +214 -0
- package/src/__tests__/toast-store.test.ts +622 -0
- package/src/__tests__/toast-timers.test.ts +163 -0
- package/src/__tests__/use-animated-target.test.tsx +60 -0
- package/src/__tests__/use-app-state.test.tsx +127 -0
- package/src/__tests__/use-toast-colors.test.tsx +189 -0
- package/src/__tests__/web-position-fixed.test.ts +70 -0
- package/src/avatar-group/AvatarGroup.web.tsx +2 -1
- package/src/benefit-list/types.ts +2 -1
- package/src/bottom-sheet/index.web.tsx +3 -2
- package/src/context-menu/index.web.tsx +3 -2
- package/src/dialog/Dialog.web.tsx +4 -3
- package/src/fab/types.ts +4 -2
- package/src/frosted-icon-button/shared.ts +1 -1
- package/src/frosted-icon-button/types.ts +2 -1
- package/src/index.ts +4 -1
- package/src/index.web.ts +4 -1
- package/src/menu/index.web.tsx +2 -1
- package/src/popover/index.web.tsx +3 -2
- package/src/portal/index.tsx +4 -1
- package/src/progressive-blur/index.tsx +78 -0
- package/src/progressive-blur/index.web.tsx +65 -0
- package/src/progressive-blur/shared.ts +81 -0
- package/src/progressive-blur/types.ts +21 -0
- package/src/select/index.web.tsx +2 -1
- package/src/styles/web-view-style.ts +21 -0
- package/src/tab-bar/TabBar.stories.tsx +217 -0
- package/src/tab-bar/TabBarBase.tsx +517 -0
- package/src/tab-bar/expo-router/RouterTabBar.tsx +80 -0
- package/src/tab-bar/expo-router/fading-tab-screen.tsx +109 -0
- package/src/tab-bar/expo-router/index.ts +13 -0
- package/src/tab-bar/glyph.native.tsx +46 -0
- package/src/tab-bar/glyph.tsx +31 -0
- package/src/tab-bar/index.ts +32 -0
- package/src/tab-bar/index.web.tsx +34 -0
- package/src/tab-bar/minimize-context.tsx +117 -0
- package/src/tab-bar/shared.ts +159 -0
- package/src/tab-bar/surface-solid.tsx +40 -0
- package/src/tab-bar/surface.native.tsx +122 -0
- package/src/tab-bar/surface.tsx +28 -0
- package/src/tab-bar/surface.web.tsx +56 -0
- package/src/tab-bar/types.ts +91 -0
- package/src/toast/Positioner.tsx +121 -0
- package/src/toast/Toast.stories.tsx +292 -65
- package/src/toast/ToastContent.tsx +405 -0
- package/src/toast/ToastHost.native.tsx +31 -0
- package/src/toast/ToastHost.tsx +67 -0
- package/src/toast/ToastIcon.tsx +55 -0
- package/src/toast/ToastRow.tsx +485 -0
- package/src/toast/ToastSwipeHandler.tsx +222 -0
- package/src/toast/Toaster.tsx +259 -0
- package/src/toast/animations.ts +313 -0
- package/src/toast/constants.ts +76 -0
- package/src/toast/context.tsx +44 -0
- package/src/toast/index.tsx +47 -123
- package/src/toast/position-utils.ts +149 -0
- package/src/toast/positioner-utils.ts +142 -0
- package/src/toast/toast-comparator.ts +41 -0
- package/src/toast/toast-fns.ts +104 -0
- package/src/toast/toast-store.ts +432 -0
- package/src/toast/toast-timers.ts +124 -0
- package/src/toast/types.ts +301 -5
- package/src/toast/use-animated-target.ts +61 -0
- package/src/toast/use-app-state.ts +77 -0
- package/src/toast/use-toast-colors.ts +133 -0
- package/src/toast/use-toast-position.ts +46 -0
- package/src/tooltip/index.web.tsx +2 -1
- package/src/zoomable-image-gallery/ZoomableImageGallery.stories.tsx +134 -0
- package/src/zoomable-image-gallery/ZoomableImageGallery.tsx +50 -27
- package/lib/commonjs/toast/Toast.js +0 -267
- package/lib/commonjs/toast/Toast.js.map +0 -1
- package/lib/commonjs/toast/const.js +0 -8
- package/lib/commonjs/toast/const.js.map +0 -1
- package/lib/commonjs/toast/index.web.js +0 -114
- package/lib/commonjs/toast/index.web.js.map +0 -1
- package/lib/commonjs/toast/sonner/index.js +0 -9
- package/lib/commonjs/toast/sonner/index.js.map +0 -1
- package/lib/commonjs/toast/sonner/index.web.js +0 -9
- package/lib/commonjs/toast/sonner/index.web.js.map +0 -1
- package/lib/module/toast/Toast.js +0 -258
- package/lib/module/toast/Toast.js.map +0 -1
- package/lib/module/toast/const.js +0 -4
- package/lib/module/toast/const.js.map +0 -1
- package/lib/module/toast/index.web.js +0 -74
- package/lib/module/toast/index.web.js.map +0 -1
- package/lib/module/toast/sonner/index.js +0 -5
- package/lib/module/toast/sonner/index.js.map +0 -1
- package/lib/module/toast/sonner/index.web.js +0 -5
- package/lib/module/toast/sonner/index.web.js.map +0 -1
- package/lib/typescript/commonjs/toast/Toast.d.ts +0 -23
- package/lib/typescript/commonjs/toast/Toast.d.ts.map +0 -1
- package/lib/typescript/commonjs/toast/const.d.ts +0 -2
- package/lib/typescript/commonjs/toast/const.d.ts.map +0 -1
- package/lib/typescript/commonjs/toast/index.web.d.ts +0 -29
- package/lib/typescript/commonjs/toast/index.web.d.ts.map +0 -1
- package/lib/typescript/commonjs/toast/sonner/index.d.ts +0 -2
- package/lib/typescript/commonjs/toast/sonner/index.d.ts.map +0 -1
- package/lib/typescript/commonjs/toast/sonner/index.web.d.ts +0 -2
- package/lib/typescript/commonjs/toast/sonner/index.web.d.ts.map +0 -1
- package/lib/typescript/module/toast/Toast.d.ts +0 -23
- package/lib/typescript/module/toast/Toast.d.ts.map +0 -1
- package/lib/typescript/module/toast/const.d.ts +0 -2
- package/lib/typescript/module/toast/const.d.ts.map +0 -1
- package/lib/typescript/module/toast/index.web.d.ts +0 -29
- package/lib/typescript/module/toast/index.web.d.ts.map +0 -1
- package/lib/typescript/module/toast/sonner/index.d.ts +0 -2
- package/lib/typescript/module/toast/sonner/index.d.ts.map +0 -1
- package/lib/typescript/module/toast/sonner/index.web.d.ts +0 -2
- package/lib/typescript/module/toast/sonner/index.web.d.ts.map +0 -1
- package/src/toast/Toast.tsx +0 -269
- package/src/toast/const.ts +0 -1
- package/src/toast/index.web.tsx +0 -101
- package/src/toast/sonner/index.ts +0 -3
- package/src/toast/sonner/index.web.ts +0 -3
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ported from expo-glass-tabs v0.1.1 — src/index.ts
|
|
3
|
+
* (MIT © 2026 David Mokos). See the top-level NOTICE.
|
|
4
|
+
*
|
|
5
|
+
* Entry for `@oxyhq/bloom/tab-bar/expo-router`. The components live in sibling
|
|
6
|
+
* modules because this file is the published entry path and must stay stable;
|
|
7
|
+
* the split also keeps the router bindings and the `TabSlot` renderer — which
|
|
8
|
+
* pull `expo-router` and `react-native-screens` respectively — in separate
|
|
9
|
+
* modules.
|
|
10
|
+
*/
|
|
11
|
+
export { RouterTabBar, RouterTabBarButton } from './RouterTabBar';
|
|
12
|
+
export type { RouterTabBarProps, RouterTabBarButtonProps } from './RouterTabBar';
|
|
13
|
+
export { renderFadingTabScreen } from './fading-tab-screen';
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ported from expo-glass-tabs v0.1.1 — src/glass-tab-bar.tsx
|
|
3
|
+
* (MIT © 2026 David Mokos). See the top-level NOTICE.
|
|
4
|
+
*
|
|
5
|
+
* NATIVE variant of a tab glyph. Identical to the neutral variant except that
|
|
6
|
+
* an item carrying an `sfSymbol` renders as a real SF Symbol on iOS: the system
|
|
7
|
+
* glyph set, weight-matched to the platform and tinted natively.
|
|
8
|
+
*
|
|
9
|
+
* `expo-symbols` is imported STATICALLY and only here — Metro selects `.native`
|
|
10
|
+
* on iOS/Android, so it never reaches a web bundle or a consumer's type-check
|
|
11
|
+
* (see the neutral `glyph.tsx` sibling). Android has no SF Symbols, so it falls
|
|
12
|
+
* through to the item's own icon node, which every item provides.
|
|
13
|
+
*/
|
|
14
|
+
import { SymbolView, type SFSymbol } from 'expo-symbols';
|
|
15
|
+
import { Platform, View } from 'react-native';
|
|
16
|
+
|
|
17
|
+
import { applyIconColor } from '../frosted-icon-button/shared';
|
|
18
|
+
import type { TabBarGlyphProps } from './shared';
|
|
19
|
+
|
|
20
|
+
export function TabBarGlyph({ item, tint, size }: TabBarGlyphProps) {
|
|
21
|
+
if (item.sfSymbol && Platform.OS === 'ios') {
|
|
22
|
+
// `TabBarItem.sfSymbol` is a plain `string` because `types.ts` may import
|
|
23
|
+
// from react/react-native only — pulling `expo-symbols`' `SFSymbol` union
|
|
24
|
+
// into the public type would drag a native-only package into every web
|
|
25
|
+
// bundle and every consumer's type-check. The narrowing happens here, at
|
|
26
|
+
// the single boundary where the symbol reaches the native view; an unknown
|
|
27
|
+
// name renders nothing rather than crashing, which is why no runtime
|
|
28
|
+
// validation is warranted.
|
|
29
|
+
return (
|
|
30
|
+
<SymbolView
|
|
31
|
+
name={item.sfSymbol as SFSymbol}
|
|
32
|
+
tintColor={tint}
|
|
33
|
+
size={size}
|
|
34
|
+
weight="semibold"
|
|
35
|
+
/>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<View style={{ height: size, alignItems: 'center', justifyContent: 'center' }}>
|
|
41
|
+
{applyIconColor(item.icon, tint)}
|
|
42
|
+
</View>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
TabBarGlyph.displayName = 'TabBarGlyph';
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ported from expo-glass-tabs v0.1.1 — src/glass-tab-bar.tsx
|
|
3
|
+
* (MIT © 2026 David Mokos). See the top-level NOTICE.
|
|
4
|
+
*
|
|
5
|
+
* NEUTRAL default variant of a tab glyph: renders the item's own `icon` node,
|
|
6
|
+
* tinted for this crossfade layer.
|
|
7
|
+
*
|
|
8
|
+
* `item.icon` is the primary icon API for the whole family — a Bloom icon
|
|
9
|
+
* element, exactly like `TabsTrigger` and `FrostedIconButton` take. `sfSymbol`
|
|
10
|
+
* is an iOS-only enhancement and is deliberately ignored here: this file is
|
|
11
|
+
* resolved by web bundlers and by a consumer's `tsc`, where a static
|
|
12
|
+
* `expo-symbols` import would break resolution. See `glyph.native.tsx` for the
|
|
13
|
+
* variant that consumes it. Both implement `TabBarGlyphProps` exactly.
|
|
14
|
+
*/
|
|
15
|
+
import { View } from 'react-native';
|
|
16
|
+
|
|
17
|
+
import { applyIconColor } from '../frosted-icon-button/shared';
|
|
18
|
+
import type { TabBarGlyphProps } from './shared';
|
|
19
|
+
|
|
20
|
+
export function TabBarGlyph({ item, tint, size }: TabBarGlyphProps) {
|
|
21
|
+
// The tint is injected as the icon's `fill` FALLBACK — an icon that sets its
|
|
22
|
+
// own `fill` (a brand mark, say) keeps it, so the crossfade layers simply
|
|
23
|
+
// render it twice at full opacity and it never flickers.
|
|
24
|
+
return (
|
|
25
|
+
<View style={{ height: size, alignItems: 'center', justifyContent: 'center' }}>
|
|
26
|
+
{applyIconColor(item.icon, tint)}
|
|
27
|
+
</View>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
TabBarGlyph.displayName = 'TabBarGlyph';
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ported from expo-glass-tabs v0.1.1 — src/index.ts
|
|
3
|
+
* (MIT © 2026 David Mokos). See the top-level NOTICE.
|
|
4
|
+
*
|
|
5
|
+
* DEFAULT entry for `@oxyhq/bloom/tab-bar`.
|
|
6
|
+
*
|
|
7
|
+
* The platform pieces are imported by their BARE relative name so Metro's
|
|
8
|
+
* platform-extension resolution picks `surface.native.tsx` / `glyph.native.tsx`
|
|
9
|
+
* on iOS and Android, and every other resolver falls back to the neutral
|
|
10
|
+
* `surface.tsx` / `glyph.tsx`. Both neutral files, and everything else this
|
|
11
|
+
* module reaches, are free of native-only imports, so a consumer's `tsc` and a
|
|
12
|
+
* non-Metro bundler resolve this entry cleanly. Web bundlers select
|
|
13
|
+
* `index.web.tsx` instead, through the package's `browser` export condition.
|
|
14
|
+
*/
|
|
15
|
+
import { ProgressiveBlur } from '../progressive-blur';
|
|
16
|
+
import { createTabBar, createTabBarButton } from './TabBarBase';
|
|
17
|
+
import { TabBarGlyph } from './glyph';
|
|
18
|
+
import { TabBarSurface } from './surface';
|
|
19
|
+
|
|
20
|
+
export const TabBar = createTabBar(TabBarSurface, ProgressiveBlur);
|
|
21
|
+
export const TabBarButton = createTabBarButton(TabBarGlyph);
|
|
22
|
+
|
|
23
|
+
export {
|
|
24
|
+
MINIMIZE_SPRING,
|
|
25
|
+
setMinimized,
|
|
26
|
+
TabBarMinimizeProvider,
|
|
27
|
+
useMinimizeOnScroll,
|
|
28
|
+
useMinimizeState,
|
|
29
|
+
useTabBarMinimized,
|
|
30
|
+
} from './minimize-context';
|
|
31
|
+
export type { MinimizeState } from './minimize-context';
|
|
32
|
+
export type { TabBarButtonProps, TabBarItem, TabBarProps, TabBarTheme } from './types';
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ported from expo-glass-tabs v0.1.1 — src/index.ts
|
|
3
|
+
* (MIT © 2026 David Mokos). See the top-level NOTICE.
|
|
4
|
+
*
|
|
5
|
+
* WEB entry for `@oxyhq/bloom/tab-bar`, selected through the package's
|
|
6
|
+
* `browser` export condition.
|
|
7
|
+
*
|
|
8
|
+
* The web modules are imported by their FULL `.web` name on purpose. Inside the
|
|
9
|
+
* published `lib/` every file is plain `.js` (`surface.js` next to
|
|
10
|
+
* `surface.web.js`), and no web bundler resolves a bare `./surface` to the
|
|
11
|
+
* `.web` sibling by extension — only Metro does that. Writing the fork path
|
|
12
|
+
* explicitly is the same thing the generated root barrel does
|
|
13
|
+
* (`src/index.web.ts` → `from './dialog/index.web'`). `./glyph` has no web fork:
|
|
14
|
+
* the neutral file already renders `item.icon`, which is the correct web
|
|
15
|
+
* behaviour, and it is what any resolver lands on here.
|
|
16
|
+
*/
|
|
17
|
+
import { ProgressiveBlur } from '../progressive-blur/index.web';
|
|
18
|
+
import { createTabBar, createTabBarButton } from './TabBarBase';
|
|
19
|
+
import { TabBarGlyph } from './glyph';
|
|
20
|
+
import { TabBarSurface } from './surface.web';
|
|
21
|
+
|
|
22
|
+
export const TabBar = createTabBar(TabBarSurface, ProgressiveBlur);
|
|
23
|
+
export const TabBarButton = createTabBarButton(TabBarGlyph);
|
|
24
|
+
|
|
25
|
+
export {
|
|
26
|
+
MINIMIZE_SPRING,
|
|
27
|
+
setMinimized,
|
|
28
|
+
TabBarMinimizeProvider,
|
|
29
|
+
useMinimizeOnScroll,
|
|
30
|
+
useMinimizeState,
|
|
31
|
+
useTabBarMinimized,
|
|
32
|
+
} from './minimize-context';
|
|
33
|
+
export type { MinimizeState } from './minimize-context';
|
|
34
|
+
export type { TabBarButtonProps, TabBarItem, TabBarProps, TabBarTheme } from './types';
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ported from expo-glass-tabs v0.1.1 — src/minimize-context.tsx
|
|
3
|
+
* (MIT © 2026 David Mokos). See the top-level NOTICE.
|
|
4
|
+
*
|
|
5
|
+
* The shared 0..1 "minimize" progress the tab bar interpolates on, plus the
|
|
6
|
+
* scroll handler that drives it. Reanimated only — no platform imports.
|
|
7
|
+
*/
|
|
8
|
+
import { createContext, useContext, useMemo, type PropsWithChildren } from 'react';
|
|
9
|
+
import {
|
|
10
|
+
useAnimatedScrollHandler,
|
|
11
|
+
useSharedValue,
|
|
12
|
+
withSpring,
|
|
13
|
+
type SharedValue,
|
|
14
|
+
} from 'react-native-reanimated';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Spring, not timing: scroll direction flips mid-animation constantly, and a
|
|
18
|
+
* spring retargets while preserving velocity — a timing curve would restart
|
|
19
|
+
* from zero and feel mechanical. Critically damped (ratio 1): no overshoot and
|
|
20
|
+
* no long settling tail, which matters because the bar animates layout.
|
|
21
|
+
*/
|
|
22
|
+
export const MINIMIZE_SPRING = { duration: 380, dampingRatio: 1 };
|
|
23
|
+
|
|
24
|
+
/** Scroll offset below which the bar is always expanded (px). */
|
|
25
|
+
const TOP_ZONE = 24;
|
|
26
|
+
/** Per-event scroll delta that counts as a deliberate direction change (px). */
|
|
27
|
+
const DIRECTION_THRESHOLD = 3;
|
|
28
|
+
|
|
29
|
+
export type MinimizeState = {
|
|
30
|
+
/** 0 = expanded (icons + labels), 1 = minimized (icons only). */
|
|
31
|
+
progress: SharedValue<number>;
|
|
32
|
+
/** Last requested target — lets writers avoid restarting the spring. */
|
|
33
|
+
target: SharedValue<number>;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const MinimizeContext = createContext<MinimizeState | null>(null);
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Wrap the tab tree once. Screens then call `useMinimizeOnScroll()` and the bar
|
|
40
|
+
* reads the same progress, so scrolling any screen minimizes the bar.
|
|
41
|
+
*/
|
|
42
|
+
export function TabBarMinimizeProvider({ children }: PropsWithChildren) {
|
|
43
|
+
const progress = useSharedValue(0);
|
|
44
|
+
const target = useSharedValue(0);
|
|
45
|
+
const state = useMemo(() => ({ progress, target }), [progress, target]);
|
|
46
|
+
return <MinimizeContext.Provider value={state}>{children}</MinimizeContext.Provider>;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
TabBarMinimizeProvider.displayName = 'TabBarMinimizeProvider';
|
|
50
|
+
|
|
51
|
+
/** Full minimize state — used by the bar, the buttons and the scroll hook. */
|
|
52
|
+
export function useMinimizeState(): MinimizeState {
|
|
53
|
+
const shared = useContext(MinimizeContext);
|
|
54
|
+
// Local fallback keeps screens working when rendered outside the provider
|
|
55
|
+
// (e.g. a web tab layout with no floating bar). Hooks run unconditionally so
|
|
56
|
+
// the order is stable whether or not a provider is present.
|
|
57
|
+
const progress = useSharedValue(0);
|
|
58
|
+
const target = useSharedValue(0);
|
|
59
|
+
const local = useMemo(() => ({ progress, target }), [progress, target]);
|
|
60
|
+
return shared ?? local;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** The animated 0..1 minimize progress (what styles interpolate on). */
|
|
64
|
+
export function useTabBarMinimized(): SharedValue<number> {
|
|
65
|
+
return useMinimizeState().progress;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Retarget the minimize spring — no-op when already heading to `next`, so
|
|
70
|
+
* per-frame scroll events never restart (and visibly stutter) the animation.
|
|
71
|
+
* Callable from both threads.
|
|
72
|
+
*/
|
|
73
|
+
export function setMinimized(state: MinimizeState, next: 0 | 1) {
|
|
74
|
+
'worklet';
|
|
75
|
+
if (state.target.value !== next) {
|
|
76
|
+
state.target.value = next;
|
|
77
|
+
state.progress.value = withSpring(next, MINIMIZE_SPRING);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Scroll handler for `Animated.ScrollView`. Scrolling down minimizes the tab
|
|
83
|
+
* bar, scrolling up (or being near the top) expands it. Offsets are clamped to
|
|
84
|
+
* the scrollable range so rubber-band overscroll can't flip the direction for a
|
|
85
|
+
* frame and flicker the bar.
|
|
86
|
+
*/
|
|
87
|
+
export function useMinimizeOnScroll() {
|
|
88
|
+
const state = useMinimizeState();
|
|
89
|
+
const previousY = useSharedValue(0);
|
|
90
|
+
|
|
91
|
+
// CRITICAL — `state` and `previousY` must stay in the dependency array. On
|
|
92
|
+
// web WITHOUT the react-native-worklets babel plugin (the production reality
|
|
93
|
+
// for every Oxy RN-Web app) reanimated cannot auto-detect what a worklet
|
|
94
|
+
// reads, so it drives the handler off its deps instead; an omitted or empty
|
|
95
|
+
// array binds the handler once against the first render's values. Native
|
|
96
|
+
// (plugin present) auto-tracks and ignores the extra deps, so listing them is
|
|
97
|
+
// correct on both platforms. Same rule as every mapper in `TabBarBase`.
|
|
98
|
+
return useAnimatedScrollHandler(
|
|
99
|
+
{
|
|
100
|
+
onScroll: (event) => {
|
|
101
|
+
const maxY = Math.max(event.contentSize.height - event.layoutMeasurement.height, 0);
|
|
102
|
+
const y = Math.min(Math.max(event.contentOffset.y, 0), maxY);
|
|
103
|
+
const dy = y - previousY.value;
|
|
104
|
+
previousY.value = y;
|
|
105
|
+
|
|
106
|
+
if (y < TOP_ZONE) {
|
|
107
|
+
setMinimized(state, 0);
|
|
108
|
+
} else if (dy > DIRECTION_THRESHOLD) {
|
|
109
|
+
setMinimized(state, 1);
|
|
110
|
+
} else if (dy < -DIRECTION_THRESHOLD) {
|
|
111
|
+
setMinimized(state, 0);
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
[state, previousY],
|
|
116
|
+
);
|
|
117
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ported from expo-glass-tabs v0.1.1 — src/glass-tab-bar.tsx
|
|
3
|
+
* (MIT © 2026 David Mokos). See the top-level NOTICE.
|
|
4
|
+
*
|
|
5
|
+
* Geometry, motion constants, theme resolution and the contracts for the two
|
|
6
|
+
* injected platform components. Everything here is platform-neutral — no
|
|
7
|
+
* expo-glass-effect, expo-symbols, expo-router or react-native-screens — because
|
|
8
|
+
* this module is pulled into the native bundle, the web bundle and a consumer's
|
|
9
|
+
* `tsc` alike.
|
|
10
|
+
*/
|
|
11
|
+
import { useMemo } from 'react';
|
|
12
|
+
import type { StyleProp, ViewStyle } from 'react-native';
|
|
13
|
+
import type { AnimatedStyle } from 'react-native-reanimated';
|
|
14
|
+
|
|
15
|
+
import { withAlpha } from '../theme/color-utils';
|
|
16
|
+
import type { ThemeColors } from '../theme/types';
|
|
17
|
+
import { useTheme } from '../theme/use-theme';
|
|
18
|
+
import type { TabBarItem, TabBarTheme } from './types';
|
|
19
|
+
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
// Geometry
|
|
22
|
+
//
|
|
23
|
+
// Every dimension the bar animates is a constant here rather than a measured
|
|
24
|
+
// layout: the highlight's position, the item box height and the capsule radius
|
|
25
|
+
// are all derived from these on the UI thread each frame. Measuring instead
|
|
26
|
+
// would put a layout round-trip between the finger and the pixels.
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
|
|
29
|
+
export const EXPANDED_HEIGHT = 58;
|
|
30
|
+
export const MINIMIZED_HEIGHT = 44;
|
|
31
|
+
/** Extra horizontal inset applied to the pill when minimized (per side). */
|
|
32
|
+
export const MINIMIZED_INSET = 34;
|
|
33
|
+
/** Outer margin between the pill and the screen edges (per side). */
|
|
34
|
+
export const BAR_MARGIN = 12;
|
|
35
|
+
/** Inner inset between the capsule wall and the tab items. */
|
|
36
|
+
export const ROW_PAD_H = 4;
|
|
37
|
+
export const LABEL_HEIGHT = 13;
|
|
38
|
+
export const ICON_SIZE = 21;
|
|
39
|
+
/**
|
|
40
|
+
* Space between icon and label — folded into the label's animated height so it
|
|
41
|
+
* fully disappears when minimized (keeps the icon perfectly centered).
|
|
42
|
+
*/
|
|
43
|
+
export const ITEM_GAP = 2;
|
|
44
|
+
export const LABEL_BLOCK = LABEL_HEIGHT + ITEM_GAP;
|
|
45
|
+
export const ITEM_PAD_V = 7;
|
|
46
|
+
/** Highlight content heights — radius must track h/2 for a true capsule. */
|
|
47
|
+
export const HIGHLIGHT_EXPANDED = ICON_SIZE + LABEL_BLOCK + ITEM_PAD_V * 2;
|
|
48
|
+
export const HIGHLIGHT_MINIMIZED = ICON_SIZE + ITEM_PAD_V * 2;
|
|
49
|
+
/** How far the bottom progressive blur bleeds above the pill. */
|
|
50
|
+
export const BLUR_BLEED = 44;
|
|
51
|
+
/** Label type size. Small by design — the icon carries the meaning. */
|
|
52
|
+
export const LABEL_FONT_SIZE = 9.5;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Slide spring: interruptible by design — rapid tab-hopping retargets with
|
|
56
|
+
* preserved velocity. Slight under-damping gives the pill a tiny settle, safe
|
|
57
|
+
* here because it's transform-only (no layout involved).
|
|
58
|
+
*/
|
|
59
|
+
export const SLIDE_SPRING = { duration: 420, dampingRatio: 0.82 };
|
|
60
|
+
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
// Theme
|
|
63
|
+
// ---------------------------------------------------------------------------
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Resolve the bar's five colors from Bloom's theme tokens, with an optional
|
|
67
|
+
* partial override on top.
|
|
68
|
+
*
|
|
69
|
+
* Upstream hardcoded a dark palette (`#FFFFFF` / `rgba(10,10,12,0.55)` / …),
|
|
70
|
+
* which would ignore the active preset and read as a black bar in a light
|
|
71
|
+
* theme. Each role maps onto the token that already carries that meaning, so
|
|
72
|
+
* the bar follows `BloomThemeProvider` for free:
|
|
73
|
+
*
|
|
74
|
+
* - the two tints are the standard foreground pair;
|
|
75
|
+
* - the highlight is `contrast50`, the token meant for a subtle raised fill;
|
|
76
|
+
* - the glass tint is a 55%-alpha page background, so the liquid-glass
|
|
77
|
+
* material behind it still refracts content;
|
|
78
|
+
* - the solid fallback is a 94%-alpha `backgroundSecondary` — near-opaque, so
|
|
79
|
+
* the bar reads as a distinct surface where there is no glass to lens.
|
|
80
|
+
*
|
|
81
|
+
* Overrides are coalesced key by key (not spread) so an explicit `undefined` in
|
|
82
|
+
* a partial can never punch a hole in the resolved theme.
|
|
83
|
+
*/
|
|
84
|
+
export function resolveTabBarTheme(
|
|
85
|
+
colors: ThemeColors,
|
|
86
|
+
overrides?: Partial<TabBarTheme>,
|
|
87
|
+
): TabBarTheme {
|
|
88
|
+
return {
|
|
89
|
+
activeTint: overrides?.activeTint ?? colors.text,
|
|
90
|
+
inactiveTint: overrides?.inactiveTint ?? colors.textSecondary,
|
|
91
|
+
highlight: overrides?.highlight ?? colors.contrast50,
|
|
92
|
+
glassTint: overrides?.glassTint ?? withAlpha(colors.background, 0.55),
|
|
93
|
+
solidFallback: overrides?.solidFallback ?? withAlpha(colors.backgroundSecondary, 0.94),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Hook form of {@link resolveTabBarTheme}.
|
|
99
|
+
*
|
|
100
|
+
* Memoized on the individual override VALUES rather than on the `overrides`
|
|
101
|
+
* object: callers pass an inline literal (`theme={{ highlight: '#…' }}`), whose
|
|
102
|
+
* identity changes every render. The resolved theme feeds a React context and a
|
|
103
|
+
* reanimated dependency array, so a fresh identity per render would re-render
|
|
104
|
+
* every button and rebuild the label mapper for nothing.
|
|
105
|
+
*/
|
|
106
|
+
export function useTabBarTheme(overrides?: Partial<TabBarTheme>): TabBarTheme {
|
|
107
|
+
const { colors } = useTheme();
|
|
108
|
+
const { activeTint, inactiveTint, highlight, glassTint, solidFallback } = overrides ?? {};
|
|
109
|
+
|
|
110
|
+
return useMemo(
|
|
111
|
+
() =>
|
|
112
|
+
resolveTabBarTheme(colors, {
|
|
113
|
+
activeTint,
|
|
114
|
+
inactiveTint,
|
|
115
|
+
highlight,
|
|
116
|
+
glassTint,
|
|
117
|
+
solidFallback,
|
|
118
|
+
}),
|
|
119
|
+
[colors, activeTint, inactiveTint, highlight, glassTint, solidFallback],
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// ---------------------------------------------------------------------------
|
|
124
|
+
// Injected platform components
|
|
125
|
+
//
|
|
126
|
+
// `TabBarBase` is platform-agnostic and receives its two platform-specific
|
|
127
|
+
// pieces as component props (the same shape as `BottomSheetBase`'s `Shell`).
|
|
128
|
+
// The three surface variants and the two glyph variants implement these exact
|
|
129
|
+
// signatures, which is what makes the resolution paths interchangeable:
|
|
130
|
+
// Metro picks `*.native.tsx`, the `browser` export condition picks the entry
|
|
131
|
+
// that imports `*.web.tsx`, everything else gets the neutral file.
|
|
132
|
+
// ---------------------------------------------------------------------------
|
|
133
|
+
|
|
134
|
+
export interface TabBarSurfaceProps {
|
|
135
|
+
/** Resolved theme — the surface picks `glassTint` or `solidFallback`. */
|
|
136
|
+
theme: TabBarTheme;
|
|
137
|
+
/**
|
|
138
|
+
* Animated capsule shape (a `borderRadius` tracking the animated height).
|
|
139
|
+
* It rides on the surface itself rather than on a clipping parent: iOS 26
|
|
140
|
+
* glass renders its own native corner configuration (true squircle + rim
|
|
141
|
+
* lighting), which an RN mask would flatten.
|
|
142
|
+
*
|
|
143
|
+
* Typed through `AnimatedStyle` because this always receives a
|
|
144
|
+
* `useAnimatedStyle` result, which reanimated 4.5 returns as an opaque
|
|
145
|
+
* `AnimatedStyleHandle` rather than the plain style object 4.2 handed back.
|
|
146
|
+
* Same reason `BottomSheetProps.style` is typed this way. Every variant
|
|
147
|
+
* forwards it into an `Animated.View` (or an animated `GlassView`), so the
|
|
148
|
+
* wider type is what they genuinely accept.
|
|
149
|
+
*/
|
|
150
|
+
style: StyleProp<AnimatedStyle<ViewStyle>>;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export interface TabBarGlyphProps {
|
|
154
|
+
item: TabBarItem;
|
|
155
|
+
/** Color for THIS layer — the bar renders one glyph per crossfade layer. */
|
|
156
|
+
tint: string;
|
|
157
|
+
/** Rendered icon size in px ({@link ICON_SIZE}). */
|
|
158
|
+
size: number;
|
|
159
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ported from expo-glass-tabs v0.1.1 — src/glass-tab-bar.tsx
|
|
3
|
+
* (MIT © 2026 David Mokos). See the top-level NOTICE.
|
|
4
|
+
*
|
|
5
|
+
* The tab bar's NON-GLASS capsule surface: a plain animated view filled with the
|
|
6
|
+
* theme's near-opaque fallback. Android, pre-iOS-26 devices and any build without
|
|
7
|
+
* a usable `expo-glass-effect` all paint this.
|
|
8
|
+
*
|
|
9
|
+
* It lives in its own module because TWO variants render it and one of them
|
|
10
|
+
* cannot reach the other: Metro resolves a bare `./surface` to
|
|
11
|
+
* `surface.native.tsx` no matter which file asks, so `surface.native.tsx`
|
|
12
|
+
* importing its neutral sibling for the fallback would import ITSELF. A name with
|
|
13
|
+
* no platform variants resolves to this one file everywhere — which is the whole
|
|
14
|
+
* point, so please do not fold it back into `surface.tsx`.
|
|
15
|
+
*/
|
|
16
|
+
import { StyleSheet } from 'react-native';
|
|
17
|
+
import Animated from 'react-native-reanimated';
|
|
18
|
+
|
|
19
|
+
import type { TabBarSurfaceProps } from './shared';
|
|
20
|
+
|
|
21
|
+
export function SolidTabBarSurface({ theme, style }: TabBarSurfaceProps) {
|
|
22
|
+
return (
|
|
23
|
+
<Animated.View
|
|
24
|
+
style={[
|
|
25
|
+
StyleSheet.absoluteFill,
|
|
26
|
+
styles.surface,
|
|
27
|
+
{ backgroundColor: theme.solidFallback },
|
|
28
|
+
style,
|
|
29
|
+
]}
|
|
30
|
+
/>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
SolidTabBarSurface.displayName = 'SolidTabBarSurface';
|
|
35
|
+
|
|
36
|
+
const styles = StyleSheet.create({
|
|
37
|
+
surface: {
|
|
38
|
+
borderCurve: 'continuous',
|
|
39
|
+
},
|
|
40
|
+
});
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ported from expo-glass-tabs v0.1.1 — src/glass-tab-bar.tsx
|
|
3
|
+
* (MIT © 2026 David Mokos). See the top-level NOTICE.
|
|
4
|
+
*
|
|
5
|
+
* NATIVE variant of the tab bar's capsule surface — real liquid glass, degrading
|
|
6
|
+
* to the solid surface whenever the glass is not actually usable.
|
|
7
|
+
*
|
|
8
|
+
* `expo-glass-effect` is imported STATICALLY and this file is the only place it
|
|
9
|
+
* appears: Metro selects `.native` on iOS/Android, so the import never reaches
|
|
10
|
+
* a web bundle or a consumer's type-check (that is what the neutral
|
|
11
|
+
* `surface.tsx` sibling is for). A peer dependency plus a static import plus a
|
|
12
|
+
* runtime capability check is the deliberate shape here — not a lazy
|
|
13
|
+
* `require()`, which Metro cannot bundle from published `lib/` when the module
|
|
14
|
+
* name is dynamic and which would also hide the dependency from consumers.
|
|
15
|
+
*
|
|
16
|
+
* `isLiquidGlassAvailable()` is false on Android and pre-iOS-26, where the
|
|
17
|
+
* package's `GlassView` has no material to render; those platforms get the same
|
|
18
|
+
* opaque fallback the neutral variant paints. "Installed" is not "usable"
|
|
19
|
+
* though, and BOTH remaining hazards sit at MODULE scope, which is why neither
|
|
20
|
+
* can be handled by a branch inside the component:
|
|
21
|
+
*
|
|
22
|
+
* 1. THE NATIVE MODULE. On iOS `isLiquidGlassAvailable()` resolves
|
|
23
|
+
* `ExpoGlassEffect` through `requireNativeModule`, which THROWS
|
|
24
|
+
* `Cannot find native module …` by contract when that module is not in the
|
|
25
|
+
* binary. For these apps it is a normal deploy state rather than a
|
|
26
|
+
* misconfiguration: an OTA JS update can land on a binary built before the
|
|
27
|
+
* package was linked, while the JS side always resolves because expo-router
|
|
28
|
+
* depends on it. Unguarded, the throw escapes render and takes down the whole
|
|
29
|
+
* screen the bar is on.
|
|
30
|
+
* 2. THE EXPORTS. `Animated.createAnimatedComponent(GlassView)` runs at IMPORT
|
|
31
|
+
* time, so a tree that resolves the specifier to something without
|
|
32
|
+
* `GlassView` hands React an `undefined` element type before any render
|
|
33
|
+
* happens.
|
|
34
|
+
*
|
|
35
|
+
* `isGlassEffectAPIAvailable()` is upstream's own third condition: on some iOS 26
|
|
36
|
+
* betas `UIGlassEffect` is missing and touching `GlassView` crashes NATIVELY,
|
|
37
|
+
* below JS (expo/expo#40911). It first shipped in expo-glass-effect 0.1.9, which is
|
|
38
|
+
* exactly why the peer floor is `>=0.1.9`: this file imports the symbol STATICALLY,
|
|
39
|
+
* and a floor predating it would be the same incoherence as declaring a
|
|
40
|
+
* statically-imported package optional. The `typeof` guard below is still not
|
|
41
|
+
* redundant — a peer range only WARNS, so a consumer can resolve an older copy
|
|
42
|
+
* anyway. A missing probe therefore means "not applicable", never "unavailable";
|
|
43
|
+
* reading it the other way would delete the glass look from every working device.
|
|
44
|
+
*
|
|
45
|
+
* Everything that fails routes to the SAME solid surface Android already paints —
|
|
46
|
+
* the intended fallback path, not a new one.
|
|
47
|
+
*/
|
|
48
|
+
import { GlassView, isGlassEffectAPIAvailable, isLiquidGlassAvailable } from 'expo-glass-effect';
|
|
49
|
+
import { StyleSheet } from 'react-native';
|
|
50
|
+
import Animated from 'react-native-reanimated';
|
|
51
|
+
|
|
52
|
+
import type { TabBarSurfaceProps } from './shared';
|
|
53
|
+
import { SolidTabBarSurface } from './surface-solid';
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* The animated glass view, or `null` when the package did not deliver the two
|
|
57
|
+
* exports this file needs. Built once, and guarded HERE rather than in the
|
|
58
|
+
* component because `createAnimatedComponent` runs on import (hazard 2 above).
|
|
59
|
+
*/
|
|
60
|
+
const AnimatedGlassView =
|
|
61
|
+
Boolean(GlassView) && typeof isLiquidGlassAvailable === 'function'
|
|
62
|
+
? Animated.createAnimatedComponent(GlassView)
|
|
63
|
+
: null;
|
|
64
|
+
|
|
65
|
+
/** Memo for {@link glassIsUsable} — the answer cannot change within a session. */
|
|
66
|
+
let glassUsable: boolean | undefined;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Whether this build can really render glass. Probed once: the native lookup
|
|
70
|
+
* behind it is not free, and on the failing path it throws.
|
|
71
|
+
*
|
|
72
|
+
* The `catch` reports rather than swallows. A bar that silently painted itself
|
|
73
|
+
* opaque on every iOS device would be far more expensive to find than one warning
|
|
74
|
+
* line, and reaching this branch always means a real, fixable packaging mistake.
|
|
75
|
+
* Warning exactly once falls out of the memo — the body runs at most one time.
|
|
76
|
+
*/
|
|
77
|
+
function glassIsUsable(): boolean {
|
|
78
|
+
if (glassUsable !== undefined) return glassUsable;
|
|
79
|
+
|
|
80
|
+
try {
|
|
81
|
+
glassUsable =
|
|
82
|
+
isLiquidGlassAvailable() &&
|
|
83
|
+
(typeof isGlassEffectAPIAvailable !== 'function' || isGlassEffectAPIAvailable());
|
|
84
|
+
} catch (error) {
|
|
85
|
+
glassUsable = false;
|
|
86
|
+
// eslint-disable-next-line no-console
|
|
87
|
+
console.warn(
|
|
88
|
+
'[Bloom] TabBar: expo-glass-effect could not report liquid-glass availability, ' +
|
|
89
|
+
'so the bar is painting its solid surface. Install expo-glass-effect and ' +
|
|
90
|
+
'rebuild the native app to get the glass capsule.',
|
|
91
|
+
error,
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return glassUsable;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function TabBarSurface({ theme, style }: TabBarSurfaceProps) {
|
|
99
|
+
if (AnimatedGlassView !== null && glassIsUsable()) {
|
|
100
|
+
return (
|
|
101
|
+
<AnimatedGlassView
|
|
102
|
+
glassEffectStyle="regular"
|
|
103
|
+
style={[
|
|
104
|
+
StyleSheet.absoluteFill,
|
|
105
|
+
styles.surface,
|
|
106
|
+
{ backgroundColor: theme.glassTint },
|
|
107
|
+
style,
|
|
108
|
+
]}
|
|
109
|
+
/>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return <SolidTabBarSurface theme={theme} style={style} />;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
TabBarSurface.displayName = 'TabBarSurface';
|
|
117
|
+
|
|
118
|
+
const styles = StyleSheet.create({
|
|
119
|
+
surface: {
|
|
120
|
+
borderCurve: 'continuous',
|
|
121
|
+
},
|
|
122
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ported from expo-glass-tabs v0.1.1 — src/glass-tab-bar.tsx
|
|
3
|
+
* (MIT © 2026 David Mokos). See the top-level NOTICE.
|
|
4
|
+
*
|
|
5
|
+
* NEUTRAL default variant of the tab bar's capsule surface: the non-glass one.
|
|
6
|
+
*
|
|
7
|
+
* This is the file resolved by everything that does NOT do React Native's
|
|
8
|
+
* platform-extension resolution — a consumer's `tsc` (which follows Bloom's
|
|
9
|
+
* `"react-native"` source export condition) and any non-Metro bundler reading
|
|
10
|
+
* the published `lib/`. It therefore imports NOTHING platform-specific:
|
|
11
|
+
* `expo-glass-effect` is native-only, and a static import of it from a file a
|
|
12
|
+
* web bundler or a consumer's type-checker resolves would break module
|
|
13
|
+
* resolution outright. Same three-way split, for the same reason, as
|
|
14
|
+
* `theme/native-root-vars{,.native,.web}.ts`.
|
|
15
|
+
*
|
|
16
|
+
* The surface itself lives in `surface-solid.tsx`, because `surface.native.tsx`
|
|
17
|
+
* renders it as its own fallback and cannot import this file to get it — Metro
|
|
18
|
+
* resolves `./surface` back to `surface.native.tsx`, i.e. to itself. This module's
|
|
19
|
+
* job is to give that one implementation the name every entry module imports.
|
|
20
|
+
*
|
|
21
|
+
* The variants — all three implement `TabBarSurfaceProps` exactly, so the entry
|
|
22
|
+
* modules can swap them freely:
|
|
23
|
+
* - `surface.native.tsx` — iOS/Android (Metro), real `UIGlassEffect` glass, with
|
|
24
|
+
* the solid surface as its fallback;
|
|
25
|
+
* - `surface.web.tsx` — web, a CSS `backdrop-filter`;
|
|
26
|
+
* - this file — everywhere else, the opaque fallback alone.
|
|
27
|
+
*/
|
|
28
|
+
export { SolidTabBarSurface as TabBarSurface } from './surface-solid';
|