@oxyhq/bloom 0.59.1 → 0.59.2

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 (56) hide show
  1. package/README.md +3 -2
  2. package/lib/commonjs/bottom-sheet/BottomSheetBase.js +16 -17
  3. package/lib/commonjs/bottom-sheet/BottomSheetBase.js.map +1 -1
  4. package/lib/commonjs/dialog/Dialog.js +1 -5
  5. package/lib/commonjs/dialog/Dialog.js.map +1 -1
  6. package/lib/commonjs/dialog/DialogBottomSheet.js +0 -4
  7. package/lib/commonjs/dialog/DialogBottomSheet.js.map +1 -1
  8. package/lib/commonjs/dialog/SheetShell.js +1 -2
  9. package/lib/commonjs/dialog/SheetShell.js.map +1 -1
  10. package/lib/commonjs/overlay/blur-target.js +53 -0
  11. package/lib/commonjs/overlay/blur-target.js.map +1 -0
  12. package/lib/commonjs/overlay/index.js +6 -4
  13. package/lib/commonjs/overlay/index.js.map +1 -1
  14. package/lib/commonjs/provider/index.js +4 -6
  15. package/lib/commonjs/provider/index.js.map +1 -1
  16. package/lib/module/bottom-sheet/BottomSheetBase.js +17 -18
  17. package/lib/module/bottom-sheet/BottomSheetBase.js.map +1 -1
  18. package/lib/module/dialog/Dialog.js +1 -5
  19. package/lib/module/dialog/Dialog.js.map +1 -1
  20. package/lib/module/dialog/DialogBottomSheet.js +1 -5
  21. package/lib/module/dialog/DialogBottomSheet.js.map +1 -1
  22. package/lib/module/dialog/SheetShell.js +1 -2
  23. package/lib/module/dialog/SheetShell.js.map +1 -1
  24. package/lib/module/overlay/blur-target.js +48 -0
  25. package/lib/module/overlay/blur-target.js.map +1 -0
  26. package/lib/module/overlay/index.js +6 -4
  27. package/lib/module/overlay/index.js.map +1 -1
  28. package/lib/module/provider/index.js +4 -6
  29. package/lib/module/provider/index.js.map +1 -1
  30. package/lib/typescript/commonjs/bottom-sheet/BottomSheetBase.d.ts.map +1 -1
  31. package/lib/typescript/commonjs/dialog/Dialog.d.ts.map +1 -1
  32. package/lib/typescript/commonjs/dialog/DialogBottomSheet.d.ts.map +1 -1
  33. package/lib/typescript/commonjs/dialog/SheetShell.d.ts.map +1 -1
  34. package/lib/typescript/commonjs/overlay/blur-target.d.ts +21 -0
  35. package/lib/typescript/commonjs/overlay/blur-target.d.ts.map +1 -0
  36. package/lib/typescript/commonjs/overlay/index.d.ts +4 -2
  37. package/lib/typescript/commonjs/overlay/index.d.ts.map +1 -1
  38. package/lib/typescript/commonjs/provider/index.d.ts.map +1 -1
  39. package/lib/typescript/module/bottom-sheet/BottomSheetBase.d.ts.map +1 -1
  40. package/lib/typescript/module/dialog/Dialog.d.ts.map +1 -1
  41. package/lib/typescript/module/dialog/DialogBottomSheet.d.ts.map +1 -1
  42. package/lib/typescript/module/dialog/SheetShell.d.ts.map +1 -1
  43. package/lib/typescript/module/overlay/blur-target.d.ts +21 -0
  44. package/lib/typescript/module/overlay/blur-target.d.ts.map +1 -0
  45. package/lib/typescript/module/overlay/index.d.ts +4 -2
  46. package/lib/typescript/module/overlay/index.d.ts.map +1 -1
  47. package/lib/typescript/module/provider/index.d.ts.map +1 -1
  48. package/package.json +1 -1
  49. package/src/__tests__/BottomSheet.test.tsx +46 -1
  50. package/src/bottom-sheet/BottomSheetBase.tsx +16 -17
  51. package/src/dialog/Dialog.tsx +1 -4
  52. package/src/dialog/DialogBottomSheet.tsx +0 -4
  53. package/src/dialog/SheetShell.tsx +1 -2
  54. package/src/overlay/blur-target.tsx +45 -0
  55. package/src/overlay/index.tsx +9 -4
  56. package/src/provider/index.tsx +14 -11
@@ -1 +1 @@
1
- {"version":3,"file":"SheetShell.d.ts","sourceRoot":"","sources":["../../../../src/dialog/SheetShell.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAA4D,MAAM,OAAO,CAAC;AACjF,OAAO,EAA+B,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAM3F,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,kBAAkB,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,qEAAqE;IACrE,YAAY,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACpC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,KAAK,EACL,MAAM,EACN,OAAO,EACP,YAAY,EACZ,QAAQ,GACT,EAAE,eAAe,2CAwEjB"}
1
+ {"version":3,"file":"SheetShell.d.ts","sourceRoot":"","sources":["../../../../src/dialog/SheetShell.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAA4D,MAAM,OAAO,CAAC;AACjF,OAAO,EAA+B,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAM3F,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,kBAAkB,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,qEAAqE;IACrE,YAAY,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACpC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,KAAK,EACL,MAAM,EACN,OAAO,EACP,YAAY,EACZ,QAAQ,GACT,EAAE,eAAe,2CAuEjB"}
@@ -0,0 +1,21 @@
1
+ import { type ReactNode, type RefObject } from 'react';
2
+ import { type View } from 'react-native';
3
+ type BlurTargetRef = RefObject<View | null>;
4
+ /**
5
+ * Gives Android overlay blurs a real view to sample.
6
+ *
7
+ * Expo Blur 56+ intentionally disables the Dimezis implementation unless a
8
+ * `BlurTargetView` is supplied. Bloom's sheets render their backdrop inside a
9
+ * native `Modal`, so the target must live around the app content in the
10
+ * underlying window and travel to the modal through React context.
11
+ *
12
+ * Only modal backdrops consume this target. Ordinary in-tree BlurViews never
13
+ * target their own ancestor, avoiding the recursive capture/crash that causes.
14
+ */
15
+ export declare function BloomBlurTargetProvider({ children }: {
16
+ children: ReactNode;
17
+ }): import("react/jsx-runtime").JSX.Element;
18
+ /** Internal target used only by Bloom's native modal backdrops. */
19
+ export declare function useBloomBlurTarget(): BlurTargetRef | null;
20
+ export {};
21
+ //# sourceMappingURL=blur-target.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blur-target.d.ts","sourceRoot":"","sources":["../../../../src/overlay/blur-target.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqC,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE1F,OAAO,EAAwB,KAAK,IAAI,EAAE,MAAM,cAAc,CAAC;AAE/D,KAAK,aAAa,GAAG,SAAS,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;AAI5C;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,2CAc5E;AAED,mEAAmE;AACnE,wBAAgB,kBAAkB,IAAI,aAAa,GAAG,IAAI,CAEzD"}
@@ -39,8 +39,8 @@
39
39
  * Use `<OverlayRoot>` for the surface's outermost node and `<Backdrop>` for its
40
40
  * dimming layer; do not re-implement either with raw `View`s.
41
41
  */
42
- import { type ReactNode } from 'react';
43
- import { View, type StyleProp, type ViewStyle } from 'react-native';
42
+ import { type ReactNode, type RefObject } from 'react';
43
+ import { View, type StyleProp, type View as NativeView, type ViewStyle } from 'react-native';
44
44
  /**
45
45
  * One blur radius for every Bloom overlay. Surfaces differ in what they show,
46
46
  * not in how the app behind them recedes.
@@ -76,6 +76,8 @@ export interface BackdropProps {
76
76
  dimColor?: string;
77
77
  /** Dim opacity, 0–1. */
78
78
  dimOpacity?: number;
79
+ /** Android view sampled by the native blur. Modal surfaces receive this from BloomProvider. */
80
+ blurTarget?: RefObject<NativeView | null>;
79
81
  /** Extra style on the press target — animated opacity, insets, z-index. */
80
82
  style?: StyleProp<ViewStyle>;
81
83
  /** Rendered ON TOP of the dim, inside the press target (Dialog's panel does this). */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/overlay/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,OAAO,EAAoB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEzD,OAAO,EAIL,IAAI,EACJ,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAItB;;;GAGG;AACH,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C,6EAA6E;AAC7E,eAAO,MAAM,oBAAoB,OAAO,CAAC;AAEzC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,gBAAgB,2CAMxE;yBANe,WAAW;;;AAU3B,MAAM,WAAW,aAAa;IAC5B,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,iFAAiF;IACjF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6DAA6D;IAC7D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iFAAiF;IACjF,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;IACxC,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wBAAwB;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,sFAAsF;IACtF,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,eAAO,MAAM,QAAQ,2FAuDlB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/overlay/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,OAAO,EAAoB,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEzE,OAAO,EAIL,IAAI,EACJ,KAAK,SAAS,EACd,KAAK,IAAI,IAAI,UAAU,EACvB,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAItB;;;GAGG;AACH,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C,6EAA6E;AAC7E,eAAO,MAAM,oBAAoB,OAAO,CAAC;AAEzC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,gBAAgB,2CAMxE;yBANe,WAAW;;;AAU3B,MAAM,WAAW,aAAa;IAC5B,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,iFAAiF;IACjF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6DAA6D;IAC7D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iFAAiF;IACjF,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;IACxC,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wBAAwB;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+FAA+F;IAC/F,UAAU,CAAC,EAAE,SAAS,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IAC1C,2EAA2E;IAC3E,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,sFAAsF;IACtF,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,eAAO,MAAM,QAAQ,2FAyDlB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/provider/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAyB,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAG9E,OAAO,EAAsB,KAAK,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAG5E,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAAC,uBAAuB,EAAE,UAAU,CAAC;IACnF,QAAQ,EAAE,SAAS,CAAC;IACpB;;;;OAIG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,wFAAwF;IACxF,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,aAAa,EACb,OAAc,EACd,GAAG,UAAU,EACd,EAAE,kBAAkB,2CAcpB;yBAnBe,aAAa"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/provider/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAyB,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAI9E,OAAO,EAAsB,KAAK,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAG5E,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAAC,uBAAuB,EAAE,UAAU,CAAC;IACnF,QAAQ,EAAE,SAAS,CAAC;IACpB;;;;OAIG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,wFAAwF;IACxF,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,aAAa,EACb,OAAc,EACd,GAAG,UAAU,EACd,EAAE,kBAAkB,2CAgBpB;yBArBe,aAAa"}
@@ -1 +1 @@
1
- {"version":3,"file":"BottomSheetBase.d.ts","sourceRoot":"","sources":["../../../../src/bottom-sheet/BottomSheetBase.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAMH,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACd,KAAK,SAAS,EACjB,MAAM,cAAc,CAAC;AAItB,OAAiB,EACb,KAAK,aAAa,EAGlB,KAAK,WAAW,EAMnB,MAAM,yBAAyB,CAAC;AAyBjC,MAAM,WAAW,cAAc;IAC3B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;CACrD;AAED,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B;;;;;;;;OAQG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;KAAE,KAAK,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC;IAC7F,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;KAAE,KAAK,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC;IACjH;;;;;OAKG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC;IAC5C,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,gBAAgB,CAAC,EAAE,MAAM,OAAO,CAAC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;;;;;OAUG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;;;;;;;;;OAcG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,MAAM,KAAK,CAAC,SAAS,CAAC;IACxC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC9B;;;;OAIG;IACH,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAChC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;CACjD;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,qBAAqB;IAClC,kEAAkE;IAClE,OAAO,EAAE,OAAO,CAAC;IACjB,gFAAgF;IAChF,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B;;;OAGG;IACH,cAAc,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACpC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC7B;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,oBAAqB,SAAQ,gBAAgB;IAC1D,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC,qBAAqB,CAAC,CAAC;CACrD;AAID,eAAO,MAAM,eAAe,6FA4mB1B,CAAC"}
1
+ {"version":3,"file":"BottomSheetBase.d.ts","sourceRoot":"","sources":["../../../../src/bottom-sheet/BottomSheetBase.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAMH,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACd,KAAK,SAAS,EACjB,MAAM,cAAc,CAAC;AAItB,OAAiB,EACb,KAAK,aAAa,EAGlB,KAAK,WAAW,EAMnB,MAAM,yBAAyB,CAAC;AA0BjC,MAAM,WAAW,cAAc;IAC3B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;CACrD;AAED,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B;;;;;;;;OAQG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;KAAE,KAAK,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC;IAC7F,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;KAAE,KAAK,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC;IACjH;;;;;OAKG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC;IAC5C,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,gBAAgB,CAAC,EAAE,MAAM,OAAO,CAAC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;;;;;OAUG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;;;;;;;;;OAcG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,MAAM,KAAK,CAAC,SAAS,CAAC;IACxC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC9B;;;;OAIG;IACH,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAChC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;CACjD;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,qBAAqB;IAClC,kEAAkE;IAClE,OAAO,EAAE,OAAO,CAAC;IACjB,gFAAgF;IAChF,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B;;;OAGG;IACH,cAAc,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACpC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC7B;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,oBAAqB,SAAQ,gBAAgB;IAC1D,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC,qBAAqB,CAAC,CAAC;CACrD;AAID,eAAO,MAAM,eAAe,6FA6mB1B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Dialog.d.ts","sourceRoot":"","sources":["../../../../src/dialog/Dialog.tsx"],"names":[],"mappings":"AA0CA,OAAO,EAIL,4BAA4B,EAK7B,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EACV,YAAY,EAGZ,WAAW,EACZ,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,4BAA4B,EAAE,CAAC;AAExC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,MAAM,CAAC,EACrB,SAAS,EACT,GAAG,IAAI,EACR,EAAE,WAAW,2CAab;AA+fD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,EACL,WAAW,EACX,OAAO,EACP,SAAS,GACV,EAAE;IACD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB,2CAoBA"}
1
+ {"version":3,"file":"Dialog.d.ts","sourceRoot":"","sources":["../../../../src/dialog/Dialog.tsx"],"names":[],"mappings":"AA0CA,OAAO,EAIL,4BAA4B,EAK7B,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EACV,YAAY,EAGZ,WAAW,EACZ,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,4BAA4B,EAAE,CAAC;AAExC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,MAAM,CAAC,EACrB,SAAS,EACT,GAAG,IAAI,EACR,EAAE,WAAW,2CAab;AA4fD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,EACL,WAAW,EACX,OAAO,EACP,SAAS,GACV,EAAE;IACD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB,2CAoBA"}
@@ -1 +1 @@
1
- {"version":3,"file":"DialogBottomSheet.d.ts","sourceRoot":"","sources":["../../../../src/dialog/DialogBottomSheet.tsx"],"names":[],"mappings":"AAkCA,OAAO,KAAK,EAAsB,WAAW,EAAE,MAAM,SAAS,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,OAAO,EACP,IAAI,EAAE,cAAc,EACpB,SAAS,EACT,OAAO,EACP,MAAM,EACN,KAAK,EACL,WAAW,EACX,OAAO,EACP,MAAM,EACN,cAAyC,EACzC,UAAiB,EACjB,iBAAwB,EACxB,cAA+C,EAC/C,UAAU,EACV,KAAK,EACL,KAAK,EACL,UAAU,EACV,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,KAAK,EACL,QAAQ,GACT,EAAE,sBAAsB,2CAmPxB;AAED;;;;GAIG;AACH,MAAM,MAAM,sBAAsB,GAAG,IAAI,CACvC,WAAW,EACT,SAAS,GACT,MAAM,GACN,WAAW,GACX,SAAS,GACT,QAAQ,GACR,OAAO,GACP,aAAa,GACb,SAAS,GACT,QAAQ,GACR,gBAAgB,GAChB,YAAY,GACZ,mBAAmB,GACnB,gBAAgB,GAChB,YAAY,GACZ,OAAO,GACP,OAAO,GACP,YAAY,GACZ,gBAAgB,GAChB,gBAAgB,GAChB,oBAAoB,GACpB,OAAO,GACP,UAAU,CACb,CAAC"}
1
+ {"version":3,"file":"DialogBottomSheet.d.ts","sourceRoot":"","sources":["../../../../src/dialog/DialogBottomSheet.tsx"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAAsB,WAAW,EAAE,MAAM,SAAS,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,OAAO,EACP,IAAI,EAAE,cAAc,EACpB,SAAS,EACT,OAAO,EACP,MAAM,EACN,KAAK,EACL,WAAW,EACX,OAAO,EACP,MAAM,EACN,cAAyC,EACzC,UAAiB,EACjB,iBAAwB,EACxB,cAA+C,EAC/C,UAAU,EACV,KAAK,EACL,KAAK,EACL,UAAU,EACV,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,KAAK,EACL,QAAQ,GACT,EAAE,sBAAsB,2CAgPxB;AAED;;;;GAIG;AACH,MAAM,MAAM,sBAAsB,GAAG,IAAI,CACvC,WAAW,EACT,SAAS,GACT,MAAM,GACN,WAAW,GACX,SAAS,GACT,QAAQ,GACR,OAAO,GACP,aAAa,GACb,SAAS,GACT,QAAQ,GACR,gBAAgB,GAChB,YAAY,GACZ,mBAAmB,GACnB,gBAAgB,GAChB,YAAY,GACZ,OAAO,GACP,OAAO,GACP,YAAY,GACZ,gBAAgB,GAChB,gBAAgB,GAChB,oBAAoB,GACpB,OAAO,GACP,UAAU,CACb,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"SheetShell.d.ts","sourceRoot":"","sources":["../../../../src/dialog/SheetShell.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAA4D,MAAM,OAAO,CAAC;AACjF,OAAO,EAA+B,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAM3F,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,kBAAkB,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,qEAAqE;IACrE,YAAY,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACpC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,KAAK,EACL,MAAM,EACN,OAAO,EACP,YAAY,EACZ,QAAQ,GACT,EAAE,eAAe,2CAwEjB"}
1
+ {"version":3,"file":"SheetShell.d.ts","sourceRoot":"","sources":["../../../../src/dialog/SheetShell.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAA4D,MAAM,OAAO,CAAC;AACjF,OAAO,EAA+B,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAM3F,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,kBAAkB,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,qEAAqE;IACrE,YAAY,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACpC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,KAAK,EACL,MAAM,EACN,OAAO,EACP,YAAY,EACZ,QAAQ,GACT,EAAE,eAAe,2CAuEjB"}
@@ -0,0 +1,21 @@
1
+ import { type ReactNode, type RefObject } from 'react';
2
+ import { type View } from 'react-native';
3
+ type BlurTargetRef = RefObject<View | null>;
4
+ /**
5
+ * Gives Android overlay blurs a real view to sample.
6
+ *
7
+ * Expo Blur 56+ intentionally disables the Dimezis implementation unless a
8
+ * `BlurTargetView` is supplied. Bloom's sheets render their backdrop inside a
9
+ * native `Modal`, so the target must live around the app content in the
10
+ * underlying window and travel to the modal through React context.
11
+ *
12
+ * Only modal backdrops consume this target. Ordinary in-tree BlurViews never
13
+ * target their own ancestor, avoiding the recursive capture/crash that causes.
14
+ */
15
+ export declare function BloomBlurTargetProvider({ children }: {
16
+ children: ReactNode;
17
+ }): import("react/jsx-runtime").JSX.Element;
18
+ /** Internal target used only by Bloom's native modal backdrops. */
19
+ export declare function useBloomBlurTarget(): BlurTargetRef | null;
20
+ export {};
21
+ //# sourceMappingURL=blur-target.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blur-target.d.ts","sourceRoot":"","sources":["../../../../src/overlay/blur-target.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqC,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE1F,OAAO,EAAwB,KAAK,IAAI,EAAE,MAAM,cAAc,CAAC;AAE/D,KAAK,aAAa,GAAG,SAAS,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;AAI5C;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,2CAc5E;AAED,mEAAmE;AACnE,wBAAgB,kBAAkB,IAAI,aAAa,GAAG,IAAI,CAEzD"}
@@ -39,8 +39,8 @@
39
39
  * Use `<OverlayRoot>` for the surface's outermost node and `<Backdrop>` for its
40
40
  * dimming layer; do not re-implement either with raw `View`s.
41
41
  */
42
- import { type ReactNode } from 'react';
43
- import { View, type StyleProp, type ViewStyle } from 'react-native';
42
+ import { type ReactNode, type RefObject } from 'react';
43
+ import { View, type StyleProp, type View as NativeView, type ViewStyle } from 'react-native';
44
44
  /**
45
45
  * One blur radius for every Bloom overlay. Surfaces differ in what they show,
46
46
  * not in how the app behind them recedes.
@@ -76,6 +76,8 @@ export interface BackdropProps {
76
76
  dimColor?: string;
77
77
  /** Dim opacity, 0–1. */
78
78
  dimOpacity?: number;
79
+ /** Android view sampled by the native blur. Modal surfaces receive this from BloomProvider. */
80
+ blurTarget?: RefObject<NativeView | null>;
79
81
  /** Extra style on the press target — animated opacity, insets, z-index. */
80
82
  style?: StyleProp<ViewStyle>;
81
83
  /** Rendered ON TOP of the dim, inside the press target (Dialog's panel does this). */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/overlay/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,OAAO,EAAoB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEzD,OAAO,EAIL,IAAI,EACJ,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAItB;;;GAGG;AACH,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C,6EAA6E;AAC7E,eAAO,MAAM,oBAAoB,OAAO,CAAC;AAEzC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,gBAAgB,2CAMxE;yBANe,WAAW;;;AAU3B,MAAM,WAAW,aAAa;IAC5B,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,iFAAiF;IACjF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6DAA6D;IAC7D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iFAAiF;IACjF,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;IACxC,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wBAAwB;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,sFAAsF;IACtF,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,eAAO,MAAM,QAAQ,2FAuDlB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/overlay/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,OAAO,EAAoB,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEzE,OAAO,EAIL,IAAI,EACJ,KAAK,SAAS,EACd,KAAK,IAAI,IAAI,UAAU,EACvB,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAItB;;;GAGG;AACH,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C,6EAA6E;AAC7E,eAAO,MAAM,oBAAoB,OAAO,CAAC;AAEzC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,gBAAgB,2CAMxE;yBANe,WAAW;;;AAU3B,MAAM,WAAW,aAAa;IAC5B,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,iFAAiF;IACjF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6DAA6D;IAC7D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iFAAiF;IACjF,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;IACxC,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wBAAwB;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+FAA+F;IAC/F,UAAU,CAAC,EAAE,SAAS,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IAC1C,2EAA2E;IAC3E,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,sFAAsF;IACtF,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,eAAO,MAAM,QAAQ,2FAyDlB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/provider/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAyB,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAG9E,OAAO,EAAsB,KAAK,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAG5E,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAAC,uBAAuB,EAAE,UAAU,CAAC;IACnF,QAAQ,EAAE,SAAS,CAAC;IACpB;;;;OAIG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,wFAAwF;IACxF,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,aAAa,EACb,OAAc,EACd,GAAG,UAAU,EACd,EAAE,kBAAkB,2CAcpB;yBAnBe,aAAa"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/provider/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAyB,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAI9E,OAAO,EAAsB,KAAK,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAG5E,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAAC,uBAAuB,EAAE,UAAU,CAAC;IACnF,QAAQ,EAAE,SAAS,CAAC;IACpB;;;;OAIG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,wFAAwF;IACxF,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,aAAa,EACb,OAAc,EACd,GAAG,UAAU,EACd,EAAE,kBAAkB,2CAgBpB;yBArBe,aAAa"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxyhq/bloom",
3
- "version": "0.59.1",
3
+ "version": "0.59.2",
4
4
  "description": "Bloom UI — Oxy ecosystem component library for React Native + Expo + Web",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",
@@ -1,9 +1,10 @@
1
1
  import React, { createRef } from 'react';
2
- import { Dimensions, Text } from 'react-native';
2
+ import { Dimensions, Platform, Text } from 'react-native';
3
3
  import { act, render, within } from '@testing-library/react-native';
4
4
 
5
5
  import { BloomThemeProvider } from '../theme/BloomThemeProvider';
6
6
  import BottomSheet, { type BottomSheetRef } from '../bottom-sheet';
7
+ import { BloomBlurTargetProvider } from '../overlay/blur-target';
7
8
 
8
9
  function renderWithTheme(ui: React.ReactElement) {
9
10
  return render(
@@ -107,6 +108,50 @@ describe('BottomSheet', () => {
107
108
  });
108
109
  });
109
110
 
111
+ describe('detached material', () => {
112
+ it('keeps the Android blur visible over a lighter dim and uses the rounder floating shape', () => {
113
+ const previousOS = Platform.OS;
114
+ Platform.OS = 'android';
115
+ try {
116
+ const ref = createRef<BottomSheetRef>();
117
+ const { UNSAFE_getByType, UNSAFE_getAllByType } = renderWithTheme(
118
+ <BloomBlurTargetProvider>
119
+ <BottomSheet ref={ref} detached>
120
+ <Text>Floating content</Text>
121
+ </BottomSheet>
122
+ </BloomBlurTargetProvider>,
123
+ );
124
+
125
+ act(() => {
126
+ ref.current?.present();
127
+ });
128
+
129
+ UNSAFE_getByType('BlurTargetView' as never);
130
+ const blur = UNSAFE_getByType('BlurView' as never);
131
+ expect(blur.props.blurMethod).toBe('dimezisBlurViewSdk31Plus');
132
+ expect(blur.props.blurTarget).toEqual(expect.objectContaining({ current: null }));
133
+
134
+ const views = UNSAFE_getAllByType('View' as never);
135
+ expect(
136
+ views.some((view) => {
137
+ const style = JSON.stringify(view.props.style);
138
+ return style.includes('"backgroundColor":"#000"') && style.includes('"opacity":0.45');
139
+ }),
140
+ ).toBe(true);
141
+
142
+ const animatedViews = UNSAFE_getAllByType('Animated.View' as never);
143
+ expect(
144
+ animatedViews.some((view) => {
145
+ const style = JSON.stringify(view.props.style);
146
+ return style.includes('"left":16') && style.includes('"borderRadius":28');
147
+ }),
148
+ ).toBe(true);
149
+ } finally {
150
+ Platform.OS = previousOS;
151
+ }
152
+ });
153
+ });
154
+
110
155
  describe('scrollable prop', () => {
111
156
  it('renders children directly when scrollable is false (no internal ScrollView wrap)', () => {
112
157
  // When scrollable={false}, the screen owns its own scrolling primitive
@@ -25,7 +25,8 @@ import Animated, {
25
25
  withTiming,
26
26
  } from 'react-native-reanimated';
27
27
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
28
- import { Backdrop } from '../overlay';
28
+ import { Backdrop, BACKDROP_DIM_OPACITY } from '../overlay';
29
+ import { useBloomBlurTarget } from '../overlay/blur-target';
29
30
  import { useTheme } from '../theme/use-theme';
30
31
 
31
32
  /** Hook that returns current screen dimensions and updates on rotation/resize. */
@@ -215,7 +216,7 @@ export const BottomSheetBase = forwardRef((props: BottomSheetBaseProps, ref: Rea
215
216
  onDismissAttempt,
216
217
  detached = false,
217
218
  showHandle = true,
218
- backdropOpacity = 0.5,
219
+ backdropOpacity = BACKDROP_DIM_OPACITY,
219
220
  scrollable = true,
220
221
  manualActivation = false,
221
222
  dynamicBackdrop = false,
@@ -226,6 +227,7 @@ export const BottomSheetBase = forwardRef((props: BottomSheetBaseProps, ref: Rea
226
227
  } = props;
227
228
 
228
229
  const insets = useSafeAreaInsets();
230
+ const blurTarget = useBloomBlurTarget();
229
231
  const theme = useTheme();
230
232
  const { colors } = theme;
231
233
  const { height: screenHeight } = useScreenDimensions();
@@ -637,11 +639,11 @@ export const BottomSheetBase = forwardRef((props: BottomSheetBaseProps, ref: Rea
637
639
  // Native (with the plugin) auto-tracks and ignores the extra deps, so this
638
640
  // is safe on both platforms. Do NOT strip the shared values from these deps.
639
641
  //
640
- // `opacity.value` drives the fade in/out (0 -> 1). `backdropOpacity` is the
641
- // final dim level once fully visible. We multiply so the consumer-provided
642
- // dim opacity applies smoothly across the animation. When
643
- // `dynamicBackdrop` is enabled, the dim also fades proportionally with
644
- // drag distance (iOS Photos style).
642
+ // `opacity.value` drives the whole blur+dim layer in/out (0 -> 1).
643
+ // `backdropOpacity` belongs ONLY to Backdrop's black dim layer below; if it
644
+ // is multiplied into this group opacity instead, the opaque black child
645
+ // hides the BlurView and Android looks like a plain dark scrim.
646
+ // `dynamicBackdrop` fades the composed blur+dim proportionally with drag.
645
647
  const backdropStyle = useAnimatedStyle(() => {
646
648
  const dragFactor = dynamicBackdrop
647
649
  ? interpolate(
@@ -652,9 +654,9 @@ export const BottomSheetBase = forwardRef((props: BottomSheetBaseProps, ref: Rea
652
654
  )
653
655
  : 1;
654
656
  return {
655
- opacity: opacity.value * backdropOpacity * dragFactor,
657
+ opacity: opacity.value * dragFactor,
656
658
  };
657
- }, [backdropOpacity, dynamicBackdrop, opacity, translateY, screenHeightSV]);
659
+ }, [dynamicBackdrop, opacity, translateY, screenHeightSV]);
658
660
 
659
661
  const sheetStyle = useAnimatedStyle(() => {
660
662
  const scale = interpolate(translateY.value, [0, screenHeightSV.value], [1, 0.95]);
@@ -792,12 +794,12 @@ export const BottomSheetBase = forwardRef((props: BottomSheetBaseProps, ref: Rea
792
794
  </Animated.View>
793
795
  ) : (
794
796
  // The ONE Bloom backdrop (blur + dim + press-to-dismiss).
795
- // `backdropStyle` drives the fade; the dim level rides on
796
- // `backdropOpacity`, so the shared component's own dim is
797
- // switched off here to keep a single source of dimming.
797
+ // `backdropStyle` drives the entrance/drag fade; the black
798
+ // dim stays translucent so the BlurView remains visible.
798
799
  <AnimatedBackdrop
799
800
  onPress={handleBackdropPress}
800
- dimOpacity={1}
801
+ dimOpacity={backdropOpacity}
802
+ blurTarget={blurTarget ?? undefined}
801
803
  style={[styles.backdrop, backdropStyle]}
802
804
  />
803
805
  )}
@@ -827,10 +829,7 @@ BottomSheetBase.displayName = 'BottomSheetBase';
827
829
 
828
830
  const styles = StyleSheet.create({
829
831
  backdrop: {
830
- // Color is solid black; the dim level is driven by `backdropOpacity` via
831
- // the animated `opacity` style on the wrapping <Animated.View>.
832
832
  flex: 1,
833
- backgroundColor: '#000',
834
833
  },
835
834
  backdropTouchable: {
836
835
  flex: 1,
@@ -846,7 +845,7 @@ const styles = StyleSheet.create({
846
845
  sheetDetached: {
847
846
  left: 16,
848
847
  right: 16,
849
- borderRadius: 24,
848
+ borderRadius: 28,
850
849
  },
851
850
  sheetNormal: {
852
851
  left: 0,
@@ -251,7 +251,7 @@ function CenteredOrSideDialog({
251
251
  // All four corners rounded — bloom's BottomSheet defaults to top-only
252
252
  // radius in flush mode, but we use `detached` so the whole card is
253
253
  // floating and rounded uniformly.
254
- borderRadius: 20,
254
+ borderRadius: 28,
255
255
  },
256
256
  // Drives the card's `height` only while a morph is in flight; at rest it
257
257
  // resolves to `height: 'auto'` — the card's normal content sizing.
@@ -344,9 +344,6 @@ function CenteredOrSideDialog({
344
344
  />
345
345
  ) : undefined
346
346
  }
347
- // Stronger dim when a Dialog is stacked over another sheet so the
348
- // underlying sheet's handle/content doesn't bleed through.
349
- backdropOpacity={0.7}
350
347
  // Measures the floating card — the size a morph starts from.
351
348
  onLayout={morphState.onPanelLayout}
352
349
  style={sheetStyle}
@@ -30,7 +30,6 @@ import {
30
30
  DEFAULT_DIALOG_CONTENT_PADDING,
31
31
  DEFAULT_MAX_HEIGHT_RATIO,
32
32
  PANEL_RADIUS,
33
- SHEET_BACKDROP_OPACITY,
34
33
  } from './placement';
35
34
  import type { DialogControlProps, DialogProps } from './types';
36
35
 
@@ -284,9 +283,6 @@ export function DialogBottomSheet({
284
283
  />
285
284
  ) : undefined
286
285
  }
287
- // Stronger dim than a lone sheet so an underlying sheet's handle/content
288
- // doesn't bleed through when a Dialog is stacked over one.
289
- backdropOpacity={SHEET_BACKDROP_OPACITY + 0.3}
290
286
  // Measures the sheet card — the size a morph starts from.
291
287
  onLayout={morphState.onPanelLayout}
292
288
  style={sheetStyle}
@@ -87,7 +87,7 @@ export function SheetShell({
87
87
  () => ({
88
88
  maxWidth: 500,
89
89
  backgroundColor: theme.colors.background,
90
- borderRadius: 20,
90
+ borderRadius: 28,
91
91
  }),
92
92
  [theme.colors.background],
93
93
  );
@@ -98,7 +98,6 @@ export function SheetShell({
98
98
  onDismiss={handleDismiss}
99
99
  enablePanDownToClose
100
100
  detached
101
- backdropOpacity={0.7}
102
101
  style={sheetStyle}
103
102
  >
104
103
  <Context.Provider value={context}>
@@ -0,0 +1,45 @@
1
+ import { createContext, useContext, useRef, type ReactNode, type RefObject } from 'react';
2
+ import { BlurTargetView } from 'expo-blur';
3
+ import { Platform, StyleSheet, type View } from 'react-native';
4
+
5
+ type BlurTargetRef = RefObject<View | null>;
6
+
7
+ const BlurTargetContext = createContext<BlurTargetRef | null>(null);
8
+
9
+ /**
10
+ * Gives Android overlay blurs a real view to sample.
11
+ *
12
+ * Expo Blur 56+ intentionally disables the Dimezis implementation unless a
13
+ * `BlurTargetView` is supplied. Bloom's sheets render their backdrop inside a
14
+ * native `Modal`, so the target must live around the app content in the
15
+ * underlying window and travel to the modal through React context.
16
+ *
17
+ * Only modal backdrops consume this target. Ordinary in-tree BlurViews never
18
+ * target their own ancestor, avoiding the recursive capture/crash that causes.
19
+ */
20
+ export function BloomBlurTargetProvider({ children }: { children: ReactNode }) {
21
+ const targetRef = useRef<View>(null);
22
+
23
+ if (Platform.OS !== 'android') {
24
+ return <>{children}</>;
25
+ }
26
+
27
+ return (
28
+ <BlurTargetContext.Provider value={targetRef}>
29
+ <BlurTargetView ref={targetRef} style={styles.target}>
30
+ {children}
31
+ </BlurTargetView>
32
+ </BlurTargetContext.Provider>
33
+ );
34
+ }
35
+
36
+ /** Internal target used only by Bloom's native modal backdrops. */
37
+ export function useBloomBlurTarget(): BlurTargetRef | null {
38
+ return useContext(BlurTargetContext);
39
+ }
40
+
41
+ const styles = StyleSheet.create({
42
+ target: {
43
+ flex: 1,
44
+ },
45
+ });
@@ -39,7 +39,7 @@
39
39
  * Use `<OverlayRoot>` for the surface's outermost node and `<Backdrop>` for its
40
40
  * dimming layer; do not re-implement either with raw `View`s.
41
41
  */
42
- import { forwardRef, memo, type ReactNode } from 'react';
42
+ import { forwardRef, memo, type ReactNode, type RefObject } from 'react';
43
43
  import { BlurView } from 'expo-blur';
44
44
  import {
45
45
  Platform,
@@ -47,6 +47,7 @@ import {
47
47
  StyleSheet,
48
48
  View,
49
49
  type StyleProp,
50
+ type View as NativeView,
50
51
  type ViewStyle,
51
52
  } from 'react-native';
52
53
 
@@ -95,6 +96,8 @@ export interface BackdropProps {
95
96
  dimColor?: string;
96
97
  /** Dim opacity, 0–1. */
97
98
  dimOpacity?: number;
99
+ /** Android view sampled by the native blur. Modal surfaces receive this from BloomProvider. */
100
+ blurTarget?: RefObject<NativeView | null>;
98
101
  /** Extra style on the press target — animated opacity, insets, z-index. */
99
102
  style?: StyleProp<ViewStyle>;
100
103
  /** Rendered ON TOP of the dim, inside the press target (Dialog's panel does this). */
@@ -116,6 +119,7 @@ export const Backdrop = memo(forwardRef<View, BackdropProps>(function Backdrop(
116
119
  blurTint = 'dark',
117
120
  dimColor = '#000',
118
121
  dimOpacity = BACKDROP_DIM_OPACITY,
122
+ blurTarget,
119
123
  style,
120
124
  children,
121
125
  accessibilityLabel = 'Dismiss',
@@ -149,9 +153,10 @@ export const Backdrop = memo(forwardRef<View, BackdropProps>(function Backdrop(
149
153
  <BlurView
150
154
  intensity={blurIntensity}
151
155
  tint={blurTint}
152
- // Android's default blur is a no-op on many devices; this is the
153
- // implementation that actually renders there.
154
- experimentalBlurMethod="dimezisBlurView"
156
+ blurTarget={blurTarget}
157
+ // Expo disables Android blur without an explicit target. Sheets get
158
+ // one from BloomProvider; targetless surfaces degrade without warning.
159
+ blurMethod={Platform.OS === 'android' && blurTarget ? 'dimezisBlurViewSdk31Plus' : undefined}
155
160
  pointerEvents="none"
156
161
  style={StyleSheet.absoluteFill}
157
162
  />
@@ -34,6 +34,7 @@ import type { ReactNode } from 'react';
34
34
 
35
35
  import { ImageResolverProvider, type ImageResolver } from '../image-resolver';
36
36
  import { BloomHapticsProvider } from '../hooks/useHaptics';
37
+ import { BloomBlurTargetProvider } from '../overlay/blur-target';
37
38
  import { TabBarMinimizeProvider } from '../tab-bar/minimize-context';
38
39
  import { BloomThemeProvider, type BloomThemeProviderProps } from '../theme';
39
40
  import { ScrollRestorationProvider } from './scroll-provider';
@@ -57,17 +58,19 @@ export function BloomProvider({
57
58
  ...themeProps
58
59
  }: BloomProviderProps) {
59
60
  return (
60
- // `value` is passed unconditionally (null when unset) so toggling a resolver
61
- // never changes the tree shape and remounts everything below it.
62
- <ImageResolverProvider value={imageResolver ?? null}>
63
- <BloomThemeProvider {...themeProps}>
64
- <ScrollRestorationProvider>
65
- <BloomHapticsProvider enabled={haptics}>
66
- <TabBarMinimizeProvider>{children}</TabBarMinimizeProvider>
67
- </BloomHapticsProvider>
68
- </ScrollRestorationProvider>
69
- </BloomThemeProvider>
70
- </ImageResolverProvider>
61
+ <BloomBlurTargetProvider>
62
+ {/* `value` is passed unconditionally (null when unset) so toggling a resolver
63
+ never changes the tree shape and remounts everything below it. */}
64
+ <ImageResolverProvider value={imageResolver ?? null}>
65
+ <BloomThemeProvider {...themeProps}>
66
+ <ScrollRestorationProvider>
67
+ <BloomHapticsProvider enabled={haptics}>
68
+ <TabBarMinimizeProvider>{children}</TabBarMinimizeProvider>
69
+ </BloomHapticsProvider>
70
+ </ScrollRestorationProvider>
71
+ </BloomThemeProvider>
72
+ </ImageResolverProvider>
73
+ </BloomBlurTargetProvider>
71
74
  );
72
75
  }
73
76