@swmansion/react-native-bottom-sheet 0.10.2 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/README.md +125 -25
  2. package/android/src/main/java/com/swmansion/reactnativebottomsheet/BottomSheetPackage.kt +1 -1
  3. package/android/src/main/java/com/swmansion/reactnativebottomsheet/BottomSheetSurfaceView.kt +10 -0
  4. package/android/src/main/java/com/swmansion/reactnativebottomsheet/BottomSheetSurfaceViewManager.kt +27 -0
  5. package/android/src/main/java/com/swmansion/reactnativebottomsheet/BottomSheetView.kt +97 -28
  6. package/android/src/main/java/com/swmansion/reactnativebottomsheet/BottomSheetViewManager.kt +11 -0
  7. package/common/cpp/react/renderer/components/ReactNativeBottomSheetSpec/ComponentDescriptors.h +4 -0
  8. package/common/cpp/react/renderer/components/ReactNativeBottomSheetSpec/ShadowNodes.h +12 -0
  9. package/ios/BottomSheetComponentView.mm +21 -2
  10. package/ios/BottomSheetContentView.h +3 -0
  11. package/ios/BottomSheetContentView.mm +15 -0
  12. package/ios/BottomSheetHostingView.swift +104 -34
  13. package/ios/BottomSheetSurfaceComponentView.h +13 -0
  14. package/ios/BottomSheetSurfaceComponentView.mm +21 -0
  15. package/lib/module/BottomSheet.js +17 -4
  16. package/lib/module/BottomSheet.js.map +1 -1
  17. package/lib/module/BottomSheetNativeComponent.ts +1 -0
  18. package/lib/module/BottomSheetSurfaceNativeComponent.ts +9 -0
  19. package/lib/module/ModalBottomSheet.js.map +1 -1
  20. package/lib/typescript/src/BottomSheet.d.ts +28 -2
  21. package/lib/typescript/src/BottomSheet.d.ts.map +1 -1
  22. package/lib/typescript/src/BottomSheetNativeComponent.d.ts +1 -0
  23. package/lib/typescript/src/BottomSheetNativeComponent.d.ts.map +1 -1
  24. package/lib/typescript/src/BottomSheetSurfaceNativeComponent.d.ts +6 -0
  25. package/lib/typescript/src/BottomSheetSurfaceNativeComponent.d.ts.map +1 -0
  26. package/lib/typescript/src/ModalBottomSheet.d.ts.map +1 -1
  27. package/package.json +20 -18
  28. package/react-native.config.js +4 -1
  29. package/src/BottomSheet.tsx +46 -1
  30. package/src/BottomSheetNativeComponent.ts +1 -0
  31. package/src/BottomSheetSurfaceNativeComponent.ts +9 -0
  32. package/src/ModalBottomSheet.tsx +4 -2
@@ -4,6 +4,7 @@ import { StyleSheet, View, useWindowDimensions } from 'react-native';
4
4
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
5
5
 
6
6
  import BottomSheetNativeComponent from './BottomSheetNativeComponent';
7
+ import BottomSheetSurfaceNativeComponent from './BottomSheetSurfaceNativeComponent';
7
8
  import { Portal } from './BottomSheetProvider';
8
9
  import { type Detent } from './bottomSheetUtils';
9
10
  export type { Detent, DetentValue } from './bottomSheetUtils';
@@ -13,8 +14,20 @@ export { programmatic } from './bottomSheetUtils';
13
14
  * Props for the inline bottom-sheet component.
14
15
  */
15
16
  export interface BottomSheetProps {
16
- /** Sheet contents, including any background or scrollable content. */
17
+ /** Sheet contents, including any scrollable content. */
17
18
  children: ReactNode;
19
+ /**
20
+ * Optional visual surface (background) rendered behind the content. The
21
+ * library sizes and positions the surface natively to cover the full sheet,
22
+ * independently of the content, so a shrinking content height never exposes
23
+ * blank space. Put a background View here instead of inside `children` when
24
+ * you want that shrink-safe behavior. When omitted, behavior is unchanged.
25
+ *
26
+ * Give the surface element a filling style such as `StyleSheet.absoluteFill`:
27
+ * it is mounted in a full-size host, so a surface sized only by its own
28
+ * content would collapse and not show.
29
+ */
30
+ surface?: ReactNode;
18
31
  /** Additional style applied to the native sheet host view. */
19
32
  style?: StyleProp<ViewStyle>;
20
33
  /** Snap points for the sheet. Defaults to `[0, 'content']`. */
@@ -39,11 +52,26 @@ export interface BottomSheetProps {
39
52
  disableScrollableNegotiation?: boolean;
40
53
  /** Scrim color used by `ModalBottomSheet`. */
41
54
  scrimColor?: string;
55
+ /**
56
+ * Scrim opacities per detent, indexed to match `detents`. Each value in 0–1
57
+ * scales the scrim color’s alpha at the detent of the same index, and the
58
+ * opacity is linearly interpolated as the sheet is dragged between detents.
59
+ * A shorter array than `detents` reuses its last value for any remaining
60
+ * detents.
61
+ *
62
+ * The default maps each detent to 0 when it is closed and 1 otherwise,
63
+ * so the scrim is transparent at any closed detent and fully opaque at every
64
+ * open one; e.g., `[0, 'content']` defaults to `[0, 1]`, and all-open detents
65
+ * default to a constant opaque scrim. Pass one value per detent—e.g.,
66
+ * `[0, 0.5, 1]`—to keep the scrim deepening across every detent.
67
+ */
68
+ scrimOpacities?: number[];
42
69
  }
43
70
 
44
71
  /** Native bottom sheet that renders inline within the current screen layout. */
45
72
  export const BottomSheet = ({
46
73
  children,
74
+ surface,
47
75
  style,
48
76
  detents = [0, 'content'],
49
77
  index,
@@ -54,6 +82,7 @@ export const BottomSheet = ({
54
82
  modal = false,
55
83
  disableScrollableNegotiation = false,
56
84
  scrimColor,
85
+ scrimOpacities,
57
86
  }: BottomSheetProps) => {
58
87
  const { height: windowHeight } = useWindowDimensions();
59
88
  const insets = useSafeAreaInsets();
@@ -82,6 +111,12 @@ export const BottomSheet = ({
82
111
  ? resolveDetentValue(detents[clampedIndex])
83
112
  : 0;
84
113
  const isCollapsed = selectedDetentValue === 0;
114
+ // Default the scrim opacity per detent: transparent at any closed detent,
115
+ // fully opaque at every open one. Mapping each detent independently keeps
116
+ // this correct regardless of the order detents are passed in.
117
+ const resolvedScrimOpacity =
118
+ scrimOpacities ??
119
+ detents.map((detent) => (resolveDetentValue(detent) === 0 ? 0 : 1));
85
120
  const handleIndexChange = (event: { nativeEvent: { index: number } }) => {
86
121
  onIndexChange?.(event.nativeEvent.index);
87
122
  };
@@ -124,10 +159,20 @@ export const BottomSheet = ({
124
159
  modal={modal}
125
160
  disableScrollableNegotiation={disableScrollableNegotiation}
126
161
  scrimColor={scrimColor}
162
+ scrimOpacities={resolvedScrimOpacity}
127
163
  onIndexChange={handleIndexChange}
128
164
  onSettle={handleSettle}
129
165
  onPositionChange={handlePositionChange}
130
166
  >
167
+ {surface != null && (
168
+ <BottomSheetSurfaceNativeComponent
169
+ collapsable={false}
170
+ pointerEvents="box-none"
171
+ style={StyleSheet.absoluteFill}
172
+ >
173
+ {surface}
174
+ </BottomSheetSurfaceNativeComponent>
175
+ )}
131
176
  <View collapsable={false} style={{ flex: 1, maxHeight }}>
132
177
  {children}
133
178
  <View collapsable={false} pointerEvents="none" />
@@ -19,6 +19,7 @@ export interface NativeProps extends ViewProps {
19
19
  modal: boolean;
20
20
  disableScrollableNegotiation?: boolean;
21
21
  scrimColor?: ColorValue;
22
+ scrimOpacities?: ReadonlyArray<CodegenTypes.Double>;
22
23
  onIndexChange?: CodegenTypes.DirectEventHandler<
23
24
  Readonly<{ index: CodegenTypes.Int32 }>
24
25
  >;
@@ -0,0 +1,9 @@
1
+ import { codegenNativeComponent, type ViewProps } from 'react-native';
2
+
3
+ // The visual surface that sits behind the sheet content. It carries no props of
4
+ // its own: the library identifies it by component type and owns its geometry,
5
+ // sizing it to cover the full sheet so a content shrink never exposes blank
6
+ // space. Its React children provide the visual appearance only.
7
+ export interface NativeProps extends ViewProps {}
8
+
9
+ export default codegenNativeComponent<NativeProps>('BottomSheetSurfaceView');
@@ -1,8 +1,10 @@
1
1
  import { BottomSheet, type BottomSheetProps } from './BottomSheet';
2
2
 
3
3
  /** Props for the modal bottom-sheet variant rendered through the provider portal. */
4
- export interface ModalBottomSheetProps
5
- extends Omit<BottomSheetProps, 'modal'> {}
4
+ export interface ModalBottomSheetProps extends Omit<
5
+ BottomSheetProps,
6
+ 'modal'
7
+ > {}
6
8
 
7
9
  /** Bottom sheet presented above the current UI with a scrim. */
8
10
  export const ModalBottomSheet = (props: ModalBottomSheetProps) => (