@swmansion/react-native-bottom-sheet 0.15.0-next.5 → 0.15.0-next.7
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/README.md +25 -2
- package/android/src/main/java/com/swmansion/reactnativebottomsheet/BottomSheetHostView.kt +979 -0
- package/android/src/main/java/com/swmansion/reactnativebottomsheet/BottomSheetView.kt +347 -858
- package/android/src/main/java/com/swmansion/reactnativebottomsheet/BottomSheetViewManager.kt +7 -1
- package/ios/BottomSheetComponentView.mm +149 -0
- package/ios/BottomSheetContentView.h +1 -0
- package/ios/BottomSheetContentView.mm +5 -0
- package/ios/BottomSheetHostingView.swift +34 -10
- package/lib/module/BottomSheet.js +26 -16
- package/lib/module/BottomSheet.js.map +1 -1
- package/lib/module/BottomSheetNativeComponent.ts +1 -0
- package/lib/module/ModalBottomSheet.js +12 -5
- package/lib/module/ModalBottomSheet.js.map +1 -1
- package/lib/typescript/src/BottomSheet.d.ts +17 -8
- package/lib/typescript/src/BottomSheet.d.ts.map +1 -1
- package/lib/typescript/src/BottomSheetNativeComponent.d.ts +1 -0
- package/lib/typescript/src/BottomSheetNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/ModalBottomSheet.d.ts +36 -2
- package/lib/typescript/src/ModalBottomSheet.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/BottomSheet.tsx +45 -23
- package/src/BottomSheetNativeComponent.ts +1 -0
- package/src/ModalBottomSheet.tsx +50 -8
package/src/BottomSheet.tsx
CHANGED
|
@@ -89,19 +89,28 @@ export interface BottomSheetProps {
|
|
|
89
89
|
wrapNativeView?: (
|
|
90
90
|
component: ComponentType<NativeProps>
|
|
91
91
|
) => ComponentType<NativeProps>;
|
|
92
|
-
/** Internal flag used by `ModalBottomSheet`. */
|
|
93
|
-
modal?: boolean;
|
|
94
92
|
/**
|
|
95
93
|
* Escape hatch that disables sheet/list gesture negotiation.
|
|
96
94
|
* If a gesture starts inside a nested scrollable, that scrollable keeps it
|
|
97
95
|
* even when it cannot scroll any further.
|
|
98
96
|
*/
|
|
99
97
|
disableScrollableNegotiation?: boolean;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
type ModalOnlyBottomSheetProps = {
|
|
101
|
+
/** Internal flag used by `ModalBottomSheet`. */
|
|
102
|
+
modal?: boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Internal flag used by `ModalBottomSheet`. When set, the sheet is presented
|
|
105
|
+
* in a native overlay above everything (including native modal screens)
|
|
106
|
+
* instead of the `BottomSheetProvider` portal.
|
|
107
|
+
*/
|
|
108
|
+
nativeOverlay?: boolean;
|
|
100
109
|
/** Scrim color used by `ModalBottomSheet`. */
|
|
101
110
|
scrimColor?: string;
|
|
102
111
|
/**
|
|
103
|
-
* Scrim opacities per detent, indexed to match `detents`. Each value in 0
|
|
104
|
-
* scales the scrim color
|
|
112
|
+
* Scrim opacities per detent, indexed to match `detents`. Each value in 0-1
|
|
113
|
+
* scales the scrim color's alpha at the detent of the same index, and the
|
|
105
114
|
* opacity is linearly interpolated as the sheet is dragged between detents.
|
|
106
115
|
* A shorter array than `detents` reuses its last value for any remaining
|
|
107
116
|
* detents.
|
|
@@ -109,29 +118,34 @@ export interface BottomSheetProps {
|
|
|
109
118
|
* The default maps each detent to 0 when it is closed and 1 otherwise,
|
|
110
119
|
* so the scrim is transparent at any closed detent and fully opaque at every
|
|
111
120
|
* open one; e.g., `[0, 'content']` defaults to `[0, 1]`, and all-open detents
|
|
112
|
-
* default to a constant opaque scrim. Pass one value per detent
|
|
113
|
-
* `[0, 0.5, 1]
|
|
121
|
+
* default to a constant opaque scrim. Pass one value per detent, e.g.
|
|
122
|
+
* `[0, 0.5, 1]`, to keep the scrim deepening across every detent.
|
|
114
123
|
*/
|
|
115
124
|
scrimOpacities?: number[];
|
|
116
|
-
}
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
export type BottomSheetInternalProps = BottomSheetProps &
|
|
128
|
+
ModalOnlyBottomSheetProps;
|
|
117
129
|
|
|
118
130
|
/** Native bottom sheet that renders inline within the current screen layout. */
|
|
119
|
-
export const BottomSheet = ({
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
131
|
+
export const BottomSheet = (props: BottomSheetProps) => {
|
|
132
|
+
const {
|
|
133
|
+
children,
|
|
134
|
+
surface,
|
|
135
|
+
style,
|
|
136
|
+
detents = [0, 'content'],
|
|
137
|
+
index,
|
|
138
|
+
animateIn = true,
|
|
139
|
+
onIndexChange,
|
|
140
|
+
onSettle,
|
|
141
|
+
onPositionChange,
|
|
142
|
+
wrapNativeView,
|
|
143
|
+
modal = false,
|
|
144
|
+
nativeOverlay = false,
|
|
145
|
+
disableScrollableNegotiation = false,
|
|
146
|
+
scrimColor,
|
|
147
|
+
scrimOpacities,
|
|
148
|
+
} = props as BottomSheetInternalProps;
|
|
135
149
|
const { height: windowHeight } = useSafeAreaFrame();
|
|
136
150
|
const insets = useSafeAreaInsets();
|
|
137
151
|
const maxHeight = windowHeight - insets.top;
|
|
@@ -165,6 +179,7 @@ export const BottomSheet = ({
|
|
|
165
179
|
const resolvedScrimOpacity =
|
|
166
180
|
scrimOpacities ??
|
|
167
181
|
detents.map((detent) => (resolveDetentValue(detent) === 0 ? 0 : 1));
|
|
182
|
+
const usesNativeOverlay = modal && nativeOverlay;
|
|
168
183
|
const handleIndexChange = (event: { nativeEvent: { index: number } }) => {
|
|
169
184
|
onIndexChange?.(event.nativeEvent.index);
|
|
170
185
|
};
|
|
@@ -213,6 +228,7 @@ export const BottomSheet = ({
|
|
|
213
228
|
index={index}
|
|
214
229
|
animateIn={animateIn}
|
|
215
230
|
modal={modal}
|
|
231
|
+
nativeOverlay={usesNativeOverlay}
|
|
216
232
|
disableScrollableNegotiation={disableScrollableNegotiation}
|
|
217
233
|
scrimColor={scrimColor}
|
|
218
234
|
scrimOpacities={resolvedScrimOpacity}
|
|
@@ -239,6 +255,12 @@ export const BottomSheet = ({
|
|
|
239
255
|
);
|
|
240
256
|
|
|
241
257
|
if (modal) {
|
|
258
|
+
// In native-overlay mode the sheet is rendered inline; the native layer
|
|
259
|
+
// reparents it into a full-screen overlay above everything (including
|
|
260
|
+
// native modal screens), so it bypasses the provider portal entirely.
|
|
261
|
+
if (usesNativeOverlay) {
|
|
262
|
+
return sheet;
|
|
263
|
+
}
|
|
242
264
|
return <Portal>{sheet}</Portal>;
|
|
243
265
|
}
|
|
244
266
|
|
|
@@ -17,6 +17,7 @@ export interface NativeProps extends ViewProps {
|
|
|
17
17
|
index: CodegenTypes.Int32;
|
|
18
18
|
animateIn?: CodegenTypes.WithDefault<boolean, true>;
|
|
19
19
|
modal: boolean;
|
|
20
|
+
nativeOverlay?: boolean;
|
|
20
21
|
disableScrollableNegotiation?: boolean;
|
|
21
22
|
scrimColor?: ColorValue;
|
|
22
23
|
scrimOpacities?: ReadonlyArray<CodegenTypes.Double>;
|
package/src/ModalBottomSheet.tsx
CHANGED
|
@@ -1,12 +1,54 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createElement } from 'react';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
BottomSheet,
|
|
5
|
+
type BottomSheetInternalProps,
|
|
6
|
+
type BottomSheetProps,
|
|
7
|
+
} from './BottomSheet';
|
|
2
8
|
|
|
3
9
|
/** Props for the modal bottom-sheet variant rendered through the provider portal. */
|
|
4
|
-
export interface ModalBottomSheetProps extends
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
10
|
+
export interface ModalBottomSheetProps extends BottomSheetProps {
|
|
11
|
+
/**
|
|
12
|
+
* Present the sheet in a native overlay above everything—including native
|
|
13
|
+
* modal screens (e.g. a React Navigation native-stack `presentation: "modal"`)
|
|
14
|
+
* —instead of the `BottomSheetProvider` portal.
|
|
15
|
+
*
|
|
16
|
+
* The portal renders into the provider's React tree, so a sheet opened from
|
|
17
|
+
* within a native modal screen is trapped inside that screen and cannot cover
|
|
18
|
+
* the full window. With `nativeOverlay`, the sheet is reparented natively into
|
|
19
|
+
* a window-level overlay (a `UIWindow`-attached container on iOS, a
|
|
20
|
+
* full-screen transparent dialog on Android) that floats above the modal.
|
|
21
|
+
*
|
|
22
|
+
* No `BottomSheetProvider` is required in this mode. The sheet sizes relative
|
|
23
|
+
* to its nearest full-size ancestor, so render it at the top level of a screen
|
|
24
|
+
* as you normally would.
|
|
25
|
+
*
|
|
26
|
+
* @default false
|
|
27
|
+
*/
|
|
28
|
+
nativeOverlay?: boolean;
|
|
29
|
+
/** Scrim color shown behind the modal sheet. */
|
|
30
|
+
scrimColor?: string;
|
|
31
|
+
/**
|
|
32
|
+
* Scrim opacities per detent, indexed to match `detents`. Each value in 0-1
|
|
33
|
+
* scales the scrim color's alpha at the detent of the same index, and the
|
|
34
|
+
* opacity is linearly interpolated as the sheet is dragged between detents.
|
|
35
|
+
* A shorter array than `detents` reuses its last value for any remaining
|
|
36
|
+
* detents.
|
|
37
|
+
*
|
|
38
|
+
* The default maps each detent to 0 when it is closed and 1 otherwise,
|
|
39
|
+
* so the scrim is transparent at any closed detent and fully opaque at every
|
|
40
|
+
* open one; e.g., `[0, 'content']` defaults to `[0, 1]`, and all-open detents
|
|
41
|
+
* default to a constant opaque scrim. Pass one value per detent, e.g.
|
|
42
|
+
* `[0, 0.5, 1]`, to keep the scrim deepening across every detent.
|
|
43
|
+
*/
|
|
44
|
+
scrimOpacities?: number[];
|
|
45
|
+
}
|
|
8
46
|
|
|
9
47
|
/** Bottom sheet presented above the current UI with a scrim. */
|
|
10
|
-
export const ModalBottomSheet = (props: ModalBottomSheetProps) =>
|
|
11
|
-
|
|
12
|
-
)
|
|
48
|
+
export const ModalBottomSheet = (props: ModalBottomSheetProps) => {
|
|
49
|
+
// `modal` lives on the internal prop set (it is hidden from the public
|
|
50
|
+
// `BottomSheet` type), so type the merged object as the internal shape rather
|
|
51
|
+
// than casting it away.
|
|
52
|
+
const internalProps: BottomSheetInternalProps = { ...props, modal: true };
|
|
53
|
+
return createElement(BottomSheet, internalProps);
|
|
54
|
+
};
|