react-native-bottom-sheet-stack 1.7.1 → 1.7.3
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/lib/commonjs/BottomSheetDefaultIndex.context.js +14 -0
- package/lib/commonjs/BottomSheetDefaultIndex.context.js.map +1 -0
- package/lib/commonjs/BottomSheetManaged.js +59 -65
- package/lib/commonjs/BottomSheetManaged.js.map +1 -1
- package/lib/commonjs/BottomSheetPersistent.js +30 -17
- package/lib/commonjs/BottomSheetPersistent.js.map +1 -1
- package/lib/commonjs/BottomSheetScaleView.js +1 -1
- package/lib/commonjs/BottomSheetScaleView.js.map +1 -1
- package/lib/commonjs/QueueItem.js +67 -77
- package/lib/commonjs/QueueItem.js.map +1 -1
- package/lib/commonjs/bottomSheetCoordinator.js +1 -3
- package/lib/commonjs/bottomSheetCoordinator.js.map +1 -1
- package/lib/commonjs/store/hooks.js +32 -2
- package/lib/commonjs/store/hooks.js.map +1 -1
- package/lib/commonjs/store/store.js +9 -6
- package/lib/commonjs/store/store.js.map +1 -1
- package/lib/commonjs/useScaleAnimation.js +29 -29
- package/lib/commonjs/useScaleAnimation.js.map +1 -1
- package/lib/commonjs/useSheetRenderData.js +17 -2
- package/lib/commonjs/useSheetRenderData.js.map +1 -1
- package/lib/typescript/src/BottomSheetDefaultIndex.context.d.ts +7 -0
- package/lib/typescript/src/BottomSheetDefaultIndex.context.d.ts.map +1 -0
- package/lib/typescript/src/BottomSheetManaged.d.ts.map +1 -1
- package/lib/typescript/src/BottomSheetPersistent.d.ts.map +1 -1
- package/lib/typescript/src/QueueItem.d.ts +1 -1
- package/lib/typescript/src/QueueItem.d.ts.map +1 -1
- package/lib/typescript/src/bottomSheetCoordinator.d.ts.map +1 -1
- package/lib/typescript/src/store/hooks.d.ts +1 -0
- package/lib/typescript/src/store/hooks.d.ts.map +1 -1
- package/lib/typescript/src/store/store.d.ts.map +1 -1
- package/lib/typescript/src/useScaleAnimation.d.ts +22 -3
- package/lib/typescript/src/useScaleAnimation.d.ts.map +1 -1
- package/lib/typescript/src/useSheetRenderData.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/BottomSheetDefaultIndex.context.ts +14 -0
- package/src/BottomSheetManaged.tsx +3 -6
- package/src/BottomSheetPersistent.tsx +7 -4
- package/src/BottomSheetScaleView.tsx +2 -2
- package/src/QueueItem.tsx +9 -5
- package/src/bottomSheetCoordinator.ts +1 -3
- package/src/store/hooks.ts +25 -0
- package/src/store/store.ts +13 -5
- package/src/useScaleAnimation.ts +18 -12
- package/src/useSheetRenderData.ts +26 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type PropsWithChildren } from 'react';
|
|
2
2
|
import { StyleSheet } from 'react-native';
|
|
3
3
|
import Animated from 'react-native-reanimated';
|
|
4
|
-
import {
|
|
4
|
+
import { useBackgroundScaleAnimatedStyle } from './useScaleAnimation';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Wraps your app content with iOS-style scale animation when a bottom sheet
|
|
@@ -19,7 +19,7 @@ import { useScaleAnimatedStyle } from './useScaleAnimation';
|
|
|
19
19
|
* ```
|
|
20
20
|
*/
|
|
21
21
|
export function BottomSheetScaleView({ children }: PropsWithChildren) {
|
|
22
|
-
const animatedStyle =
|
|
22
|
+
const animatedStyle = useBackgroundScaleAnimatedStyle();
|
|
23
23
|
|
|
24
24
|
return (
|
|
25
25
|
<Animated.View style={[styles.container, animatedStyle]}>
|
package/src/QueueItem.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useEffect } from 'react';
|
|
1
|
+
import { memo, useEffect } from 'react';
|
|
2
2
|
import { StyleSheet, View } from 'react-native';
|
|
3
3
|
import Animated from 'react-native-reanimated';
|
|
4
4
|
import { useSafeAreaFrame } from 'react-native-safe-area-context';
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
} from './bottomSheet.store';
|
|
16
16
|
import { BottomSheetBackdrop } from './BottomSheetBackdrop';
|
|
17
17
|
import { cleanupSheetRef } from './refsMap';
|
|
18
|
-
import {
|
|
18
|
+
import { useSheetScaleAnimatedStyle } from './useScaleAnimation';
|
|
19
19
|
|
|
20
20
|
interface QueueItemProps {
|
|
21
21
|
id: string;
|
|
@@ -23,7 +23,11 @@ interface QueueItemProps {
|
|
|
23
23
|
isActive: boolean;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
export
|
|
26
|
+
export const QueueItem = memo(function QueueItem({
|
|
27
|
+
id,
|
|
28
|
+
stackIndex,
|
|
29
|
+
isActive,
|
|
30
|
+
}: QueueItemProps) {
|
|
27
31
|
const content = useSheetContent(id);
|
|
28
32
|
const usePortal = useSheetUsePortal(id);
|
|
29
33
|
const keepMounted = useSheetKeepMounted(id);
|
|
@@ -31,7 +35,7 @@ export function QueueItem({ id, stackIndex, isActive }: QueueItemProps) {
|
|
|
31
35
|
const startClosing = useStartClosing();
|
|
32
36
|
|
|
33
37
|
const { width, height } = useSafeAreaFrame();
|
|
34
|
-
const scaleStyle =
|
|
38
|
+
const scaleStyle = useSheetScaleAnimatedStyle(id);
|
|
35
39
|
|
|
36
40
|
useEffect(() => {
|
|
37
41
|
return () => {
|
|
@@ -76,7 +80,7 @@ export function QueueItem({ id, stackIndex, isActive }: QueueItemProps) {
|
|
|
76
80
|
</Animated.View>
|
|
77
81
|
</>
|
|
78
82
|
);
|
|
79
|
-
}
|
|
83
|
+
});
|
|
80
84
|
|
|
81
85
|
const styles = StyleSheet.create({
|
|
82
86
|
container: {},
|
|
@@ -19,9 +19,7 @@ export function initBottomSheetCoordinator(groupId: string) {
|
|
|
19
19
|
|
|
20
20
|
switch (status) {
|
|
21
21
|
case 'opening':
|
|
22
|
-
|
|
23
|
-
getSheetRef(id)?.current?.expand();
|
|
24
|
-
});
|
|
22
|
+
getSheetRef(id)?.current?.expand();
|
|
25
23
|
break;
|
|
26
24
|
case 'hidden':
|
|
27
25
|
if (ref) ref.close();
|
package/src/store/hooks.ts
CHANGED
|
@@ -32,6 +32,31 @@ export const useIsSheetOpen = (id: string) =>
|
|
|
32
32
|
return status === 'open' || status === 'opening';
|
|
33
33
|
}, shallow);
|
|
34
34
|
|
|
35
|
+
export const useHasScaleBackgroundAbove = (id: string) =>
|
|
36
|
+
useBottomSheetStore((state) => {
|
|
37
|
+
const { stackOrder, sheetsById } = state;
|
|
38
|
+
const sheetIndex = stackOrder.indexOf(id);
|
|
39
|
+
|
|
40
|
+
if (sheetIndex === -1) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Check if any sheet above this one has scaleBackground
|
|
45
|
+
for (let i = sheetIndex + 1; i < stackOrder.length; i++) {
|
|
46
|
+
const aboveId = stackOrder[i]!;
|
|
47
|
+
const aboveSheet = sheetsById[aboveId];
|
|
48
|
+
if (
|
|
49
|
+
aboveSheet &&
|
|
50
|
+
aboveSheet.scaleBackground &&
|
|
51
|
+
aboveSheet.status !== 'closing' &&
|
|
52
|
+
aboveSheet.status !== 'hidden'
|
|
53
|
+
) {
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return false;
|
|
58
|
+
}, shallow);
|
|
59
|
+
|
|
35
60
|
// Action hooks
|
|
36
61
|
|
|
37
62
|
export const useOpen = () => useBottomSheetStore((state) => state.open);
|
package/src/store/store.ts
CHANGED
|
@@ -33,9 +33,9 @@ export const useBottomSheetStore = create(
|
|
|
33
33
|
mode
|
|
34
34
|
);
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const nextPortalSession =
|
|
36
|
+
const shouldGetNewPortalSession =
|
|
37
|
+
sheet.usePortal && (!existingSheet || !existingSheet.keepMounted);
|
|
38
|
+
const nextPortalSession = shouldGetNewPortalSession
|
|
39
39
|
? getNextPortalSession(sheet.id)
|
|
40
40
|
: undefined;
|
|
41
41
|
|
|
@@ -46,7 +46,9 @@ export const useBottomSheetStore = create(
|
|
|
46
46
|
scaleBackground:
|
|
47
47
|
sheet.scaleBackground ?? existingSheet.scaleBackground,
|
|
48
48
|
params: sheet.params ?? existingSheet.params,
|
|
49
|
-
portalSession:
|
|
49
|
+
portalSession: existingSheet.keepMounted
|
|
50
|
+
? existingSheet.portalSession
|
|
51
|
+
: (nextPortalSession ?? existingSheet.portalSession),
|
|
50
52
|
}
|
|
51
53
|
: { ...sheet, status: 'opening', portalSession: nextPortalSession };
|
|
52
54
|
|
|
@@ -144,10 +146,16 @@ export const useBottomSheetStore = create(
|
|
|
144
146
|
set((state) => {
|
|
145
147
|
if (state.sheetsById[sheet.id]) return state;
|
|
146
148
|
|
|
149
|
+
// For portal-based persistent sheets, set initial portalSession
|
|
150
|
+
// This session will be reused across open/close cycles
|
|
151
|
+
const portalSession = sheet.usePortal
|
|
152
|
+
? getNextPortalSession(sheet.id)
|
|
153
|
+
: undefined;
|
|
154
|
+
|
|
147
155
|
return {
|
|
148
156
|
sheetsById: {
|
|
149
157
|
...state.sheetsById,
|
|
150
|
-
[sheet.id]: { ...sheet, status: 'hidden' },
|
|
158
|
+
[sheet.id]: { ...sheet, status: 'hidden', portalSession },
|
|
151
159
|
},
|
|
152
160
|
};
|
|
153
161
|
}),
|
package/src/useScaleAnimation.ts
CHANGED
|
@@ -38,7 +38,7 @@ const DEFAULT_CONFIG = {
|
|
|
38
38
|
} satisfies Required<ScaleConfig>;
|
|
39
39
|
|
|
40
40
|
function useBackgroundScaleDepth(groupId: string): number {
|
|
41
|
-
|
|
41
|
+
const depth = useBottomSheetStore((state) => {
|
|
42
42
|
const { stackOrder, sheetsById } = state;
|
|
43
43
|
|
|
44
44
|
for (let i = 0; i < stackOrder.length; i++) {
|
|
@@ -55,6 +55,7 @@ function useBackgroundScaleDepth(groupId: string): number {
|
|
|
55
55
|
}
|
|
56
56
|
return 0;
|
|
57
57
|
});
|
|
58
|
+
return depth;
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
function useSheetScaleDepth(
|
|
@@ -63,7 +64,7 @@ function useSheetScaleDepth(
|
|
|
63
64
|
): number {
|
|
64
65
|
const prevDepthRef = useRef(0);
|
|
65
66
|
|
|
66
|
-
|
|
67
|
+
const result = useBottomSheetStore((state) => {
|
|
67
68
|
if (!sheetId) {
|
|
68
69
|
return 0;
|
|
69
70
|
}
|
|
@@ -93,10 +94,11 @@ function useSheetScaleDepth(
|
|
|
93
94
|
prevDepthRef.current = depth;
|
|
94
95
|
return depth;
|
|
95
96
|
});
|
|
97
|
+
return result;
|
|
96
98
|
}
|
|
97
99
|
|
|
98
|
-
|
|
99
|
-
const {
|
|
100
|
+
function useScaleAnimatedStyleInternal(scaleDepth: number) {
|
|
101
|
+
const { scaleConfig } = useBottomSheetManagerContext();
|
|
100
102
|
|
|
101
103
|
const {
|
|
102
104
|
scale = DEFAULT_CONFIG.scale,
|
|
@@ -105,14 +107,6 @@ export function useScaleAnimatedStyle({ id }: { id?: string } = {}) {
|
|
|
105
107
|
animation = DEFAULT_CONFIG.animation,
|
|
106
108
|
} = scaleConfig ?? {};
|
|
107
109
|
|
|
108
|
-
const isBackground = id === undefined;
|
|
109
|
-
|
|
110
|
-
const backgroundDepth = useBackgroundScaleDepth(groupId);
|
|
111
|
-
const sheetDepth = useSheetScaleDepth(groupId, id);
|
|
112
|
-
|
|
113
|
-
const scaleDepth = isBackground ? backgroundDepth : sheetDepth;
|
|
114
|
-
|
|
115
|
-
// Animate the depth change
|
|
116
110
|
const progress = useDerivedValue(() => {
|
|
117
111
|
if (animation.type === 'spring') {
|
|
118
112
|
return withSpring(scaleDepth, animation.config);
|
|
@@ -142,3 +136,15 @@ export function useScaleAnimatedStyle({ id }: { id?: string } = {}) {
|
|
|
142
136
|
};
|
|
143
137
|
});
|
|
144
138
|
}
|
|
139
|
+
|
|
140
|
+
export function useBackgroundScaleAnimatedStyle() {
|
|
141
|
+
const { groupId } = useBottomSheetManagerContext();
|
|
142
|
+
const scaleDepth = useBackgroundScaleDepth(groupId);
|
|
143
|
+
return useScaleAnimatedStyleInternal(scaleDepth);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export function useSheetScaleAnimatedStyle(sheetId: string) {
|
|
147
|
+
const { groupId } = useBottomSheetManagerContext();
|
|
148
|
+
const scaleDepth = useSheetScaleDepth(groupId, sheetId);
|
|
149
|
+
return useScaleAnimatedStyleInternal(scaleDepth);
|
|
150
|
+
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { shallow } from 'zustand/shallow';
|
|
2
1
|
import {
|
|
3
2
|
useBottomSheetStore,
|
|
4
3
|
type BottomSheetState,
|
|
@@ -11,6 +10,31 @@ export interface SheetRenderItem {
|
|
|
11
10
|
isActive: boolean;
|
|
12
11
|
}
|
|
13
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Deep comparison for SheetRenderItem arrays.
|
|
15
|
+
* Returns true if arrays have same items with same values.
|
|
16
|
+
*/
|
|
17
|
+
function sheetRenderDataEqual(
|
|
18
|
+
a: SheetRenderItem[],
|
|
19
|
+
b: SheetRenderItem[]
|
|
20
|
+
): boolean {
|
|
21
|
+
if (a.length !== b.length) return false;
|
|
22
|
+
|
|
23
|
+
for (let i = 0; i < a.length; i++) {
|
|
24
|
+
const itemA = a[i]!;
|
|
25
|
+
const itemB = b[i]!;
|
|
26
|
+
if (
|
|
27
|
+
itemA.id !== itemB.id ||
|
|
28
|
+
itemA.stackIndex !== itemB.stackIndex ||
|
|
29
|
+
itemA.isActive !== itemB.isActive
|
|
30
|
+
) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
|
|
14
38
|
/**
|
|
15
39
|
* Returns a flat list of sheets to render.
|
|
16
40
|
*
|
|
@@ -29,7 +53,7 @@ export function useSheetRenderData(): SheetRenderItem[] {
|
|
|
29
53
|
const active = getActiveSheets(state, groupId);
|
|
30
54
|
|
|
31
55
|
return [...hiddenPersistent, ...active];
|
|
32
|
-
},
|
|
56
|
+
}, sheetRenderDataEqual);
|
|
33
57
|
}
|
|
34
58
|
|
|
35
59
|
function getHiddenPersistentSheets(
|