react-native-bottom-sheet-stack 1.0.2 → 1.0.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/BottomSheet.context.js.map +1 -1
- package/lib/commonjs/BottomSheetBackdrop.js +76 -0
- package/lib/commonjs/BottomSheetBackdrop.js.map +1 -0
- package/lib/commonjs/BottomSheetHost.js +203 -37
- package/lib/commonjs/BottomSheetHost.js.map +1 -1
- package/lib/commonjs/BottomSheetManaged.js +128 -38
- package/lib/commonjs/BottomSheetManaged.js.map +1 -1
- package/lib/commonjs/BottomSheetManager.context.js.map +1 -1
- package/lib/commonjs/BottomSheetManager.provider.js +38 -13
- package/lib/commonjs/BottomSheetManager.provider.js.map +1 -1
- package/lib/commonjs/BottomSheetScaleView.js +67 -0
- package/lib/commonjs/BottomSheetScaleView.js.map +1 -0
- package/lib/commonjs/animatedRegistry.js +25 -0
- package/lib/commonjs/animatedRegistry.js.map +1 -0
- package/lib/commonjs/bottomSheet.store.js.map +1 -1
- package/lib/commonjs/bottomSheetCoordinator.js +5 -6
- package/lib/commonjs/bottomSheetCoordinator.js.map +1 -1
- package/lib/commonjs/index.js +3 -3
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/useBottomSheetManager.js +88 -44
- package/lib/commonjs/useBottomSheetManager.js.map +1 -1
- package/lib/commonjs/useBottomSheetState.js +40 -10
- package/lib/commonjs/useBottomSheetState.js.map +1 -1
- package/lib/commonjs/useScaleAnimation.js +108 -0
- package/lib/commonjs/useScaleAnimation.js.map +1 -0
- package/lib/typescript/example/src/App.d.ts +0 -2
- package/lib/typescript/example/src/App.d.ts.map +1 -1
- package/lib/typescript/src/BottomSheetBackdrop.d.ts +12 -0
- package/lib/typescript/src/BottomSheetBackdrop.d.ts.map +1 -0
- package/lib/typescript/src/BottomSheetHost.d.ts +1 -2
- package/lib/typescript/src/BottomSheetHost.d.ts.map +1 -1
- package/lib/typescript/src/BottomSheetManaged.d.ts.map +1 -1
- package/lib/typescript/src/BottomSheetManager.context.d.ts +2 -0
- package/lib/typescript/src/BottomSheetManager.context.d.ts.map +1 -1
- package/lib/typescript/src/BottomSheetManager.provider.d.ts +4 -3
- package/lib/typescript/src/BottomSheetManager.provider.d.ts.map +1 -1
- package/lib/typescript/src/BottomSheetScaleView.d.ts +18 -0
- package/lib/typescript/src/BottomSheetScaleView.d.ts.map +1 -0
- package/lib/typescript/src/animatedRegistry.d.ts +4 -0
- package/lib/typescript/src/animatedRegistry.d.ts.map +1 -0
- package/lib/typescript/src/bottomSheet.store.d.ts +4 -3
- package/lib/typescript/src/bottomSheet.store.d.ts.map +1 -1
- package/lib/typescript/src/bottomSheetCoordinator.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +2 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/useBottomSheetManager.d.ts.map +1 -1
- package/lib/typescript/src/useBottomSheetState.d.ts.map +1 -1
- package/lib/typescript/src/useScaleAnimation.d.ts +43 -0
- package/lib/typescript/src/useScaleAnimation.d.ts.map +1 -0
- package/package.json +9 -2
- package/src/BottomSheetBackdrop.tsx +61 -0
- package/src/BottomSheetHost.tsx +51 -13
- package/src/BottomSheetManaged.tsx +26 -33
- package/src/BottomSheetManager.context.tsx +2 -0
- package/src/BottomSheetManager.provider.tsx +10 -6
- package/src/BottomSheetScaleView.tsx +41 -0
- package/src/animatedRegistry.ts +22 -0
- package/src/bottomSheet.store.ts +124 -124
- package/src/bottomSheetCoordinator.ts +5 -6
- package/src/index.tsx +2 -4
- package/src/useBottomSheetManager.tsx +37 -48
- package/src/useBottomSheetState.ts +2 -6
- package/src/useScaleAnimation.ts +114 -0
- package/lib/commonjs/ScaleBackgroundWrapper.js +0 -71
- package/lib/commonjs/ScaleBackgroundWrapper.js.map +0 -1
- package/lib/typescript/src/ScaleBackgroundWrapper.d.ts +0 -32
- package/lib/typescript/src/ScaleBackgroundWrapper.d.ts.map +0 -1
- package/src/ScaleBackgroundWrapper.tsx +0 -97
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import BottomSheetOriginal, {
|
|
2
|
-
BottomSheetBackdrop,
|
|
3
2
|
useBottomSheetSpringConfigs,
|
|
4
|
-
type BottomSheetBackdropProps,
|
|
5
3
|
type BottomSheetProps,
|
|
6
4
|
} from '@gorhom/bottom-sheet';
|
|
7
5
|
import { type BottomSheetMethods } from '@gorhom/bottom-sheet/lib/typescript/types';
|
|
8
|
-
import React
|
|
6
|
+
import React from 'react';
|
|
9
7
|
|
|
8
|
+
import { getAnimatedIndex } from './animatedRegistry';
|
|
10
9
|
import { createSheetEventHandlers } from './bottomSheetCoordinator';
|
|
11
10
|
import { useBottomSheetState } from './useBottomSheetState';
|
|
12
11
|
|
|
@@ -14,6 +13,9 @@ export interface BottomSheetRef extends BottomSheetMethods {}
|
|
|
14
13
|
|
|
15
14
|
interface BottomSheetManagedProps extends BottomSheetProps {}
|
|
16
15
|
|
|
16
|
+
// Null backdrop - we render our own backdrop separately in BottomSheetHost
|
|
17
|
+
const nullBackdrop = () => null;
|
|
18
|
+
|
|
17
19
|
export const BottomSheetManaged = React.forwardRef<
|
|
18
20
|
BottomSheetRef,
|
|
19
21
|
BottomSheetManagedProps
|
|
@@ -24,35 +26,36 @@ export const BottomSheetManaged = React.forwardRef<
|
|
|
24
26
|
onAnimate,
|
|
25
27
|
onClose,
|
|
26
28
|
enablePanDownToClose = true,
|
|
27
|
-
backdropComponent,
|
|
29
|
+
backdropComponent = nullBackdrop,
|
|
30
|
+
animatedIndex: externalAnimatedIndex,
|
|
28
31
|
...props
|
|
29
32
|
},
|
|
30
33
|
ref
|
|
31
34
|
) => {
|
|
32
35
|
const { bottomSheetState } = useBottomSheetState();
|
|
33
36
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
);
|
|
37
|
+
// Get or create shared animated index for this sheet
|
|
38
|
+
const animatedIndex =
|
|
39
|
+
externalAnimatedIndex ?? getAnimatedIndex(bottomSheetState.id);
|
|
38
40
|
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
fromIndex: number,
|
|
42
|
-
toIndex: number,
|
|
43
|
-
fromPosition: number,
|
|
44
|
-
toPosition: number
|
|
45
|
-
) => {
|
|
46
|
-
handleAnimate(fromIndex, toIndex);
|
|
47
|
-
onAnimate?.(fromIndex, toIndex, fromPosition, toPosition);
|
|
48
|
-
},
|
|
49
|
-
[handleAnimate, onAnimate]
|
|
41
|
+
const { handleAnimate, handleClose } = createSheetEventHandlers(
|
|
42
|
+
bottomSheetState.id
|
|
50
43
|
);
|
|
51
44
|
|
|
52
|
-
const
|
|
45
|
+
const wrappedOnAnimate: BottomSheetProps['onAnimate'] = (
|
|
46
|
+
fromIndex: number,
|
|
47
|
+
toIndex: number,
|
|
48
|
+
fromPosition: number,
|
|
49
|
+
toPosition: number
|
|
50
|
+
) => {
|
|
51
|
+
handleAnimate(fromIndex, toIndex);
|
|
52
|
+
onAnimate?.(fromIndex, toIndex, fromPosition, toPosition);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const wrappedOnClose = () => {
|
|
53
56
|
onClose?.();
|
|
54
57
|
handleClose();
|
|
55
|
-
}
|
|
58
|
+
};
|
|
56
59
|
|
|
57
60
|
const config = useBottomSheetSpringConfigs({
|
|
58
61
|
stiffness: 400,
|
|
@@ -60,25 +63,15 @@ export const BottomSheetManaged = React.forwardRef<
|
|
|
60
63
|
mass: 0.7,
|
|
61
64
|
});
|
|
62
65
|
|
|
63
|
-
const renderBackdropComponent = useCallback(
|
|
64
|
-
(backdropProps: BottomSheetBackdropProps) => (
|
|
65
|
-
<BottomSheetBackdrop
|
|
66
|
-
{...backdropProps}
|
|
67
|
-
disappearsOnIndex={-1}
|
|
68
|
-
appearsOnIndex={0}
|
|
69
|
-
/>
|
|
70
|
-
),
|
|
71
|
-
[]
|
|
72
|
-
);
|
|
73
|
-
|
|
74
66
|
return (
|
|
75
67
|
<BottomSheetOriginal
|
|
76
68
|
animationConfigs={config}
|
|
77
69
|
ref={ref}
|
|
78
70
|
{...props}
|
|
71
|
+
animatedIndex={animatedIndex}
|
|
79
72
|
onClose={wrappedOnClose}
|
|
80
73
|
onAnimate={wrappedOnAnimate}
|
|
81
|
-
backdropComponent={backdropComponent
|
|
74
|
+
backdropComponent={backdropComponent}
|
|
82
75
|
enablePanDownToClose={enablePanDownToClose}
|
|
83
76
|
>
|
|
84
77
|
{children}
|
|
@@ -4,23 +4,27 @@ import {
|
|
|
4
4
|
BottomSheetManagerContext,
|
|
5
5
|
type BottomSheetManagerContextValue,
|
|
6
6
|
} from './BottomSheetManager.context';
|
|
7
|
+
import type { ScaleConfig } from './useScaleAnimation';
|
|
7
8
|
|
|
8
9
|
interface ProviderProps extends PropsWithChildren {
|
|
9
10
|
id: string;
|
|
11
|
+
scaleConfig?: ScaleConfig;
|
|
10
12
|
}
|
|
11
13
|
|
|
12
|
-
function
|
|
14
|
+
export function BottomSheetManagerProvider({
|
|
15
|
+
id,
|
|
16
|
+
scaleConfig,
|
|
17
|
+
children,
|
|
18
|
+
}: ProviderProps) {
|
|
19
|
+
const value = { groupId: id, scaleConfig };
|
|
20
|
+
|
|
13
21
|
return (
|
|
14
|
-
<BottomSheetManagerContext.Provider key={id} value={
|
|
22
|
+
<BottomSheetManagerContext.Provider key={id} value={value}>
|
|
15
23
|
{children}
|
|
16
24
|
</BottomSheetManagerContext.Provider>
|
|
17
25
|
);
|
|
18
26
|
}
|
|
19
27
|
|
|
20
|
-
export const BottomSheetManagerProvider = React.memo(
|
|
21
|
-
BottomSheetManagerProviderComp
|
|
22
|
-
);
|
|
23
|
-
|
|
24
28
|
export const useBottomSheetManagerContext =
|
|
25
29
|
(): BottomSheetManagerContextValue => {
|
|
26
30
|
const context = React.useContext(BottomSheetManagerContext);
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { useContext, type PropsWithChildren } from 'react';
|
|
2
|
+
import { StyleSheet } from 'react-native';
|
|
3
|
+
import Animated from 'react-native-reanimated';
|
|
4
|
+
import { BottomSheetManagerContext } from './BottomSheetManager.context';
|
|
5
|
+
import { useScaleAnimatedStyle, useScaleDepth } from './useScaleAnimation';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Wraps your app content with iOS-style scale animation when a bottom sheet
|
|
9
|
+
* with scaleBackground: true is open. Place your main content inside this
|
|
10
|
+
* component, but keep BottomSheetHost outside of it.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* <BottomSheetManagerProvider id="default" scaleConfig={{ scale: 0.92 }}>
|
|
15
|
+
* <BottomSheetScaleView>
|
|
16
|
+
* <MainContent />
|
|
17
|
+
* </BottomSheetScaleView>
|
|
18
|
+
* <BottomSheetHost />
|
|
19
|
+
* </BottomSheetManagerProvider>
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export function BottomSheetScaleView({ children }: PropsWithChildren) {
|
|
23
|
+
const context = useContext(BottomSheetManagerContext);
|
|
24
|
+
const groupId = context?.groupId ?? 'default';
|
|
25
|
+
const scaleConfig = context?.scaleConfig;
|
|
26
|
+
|
|
27
|
+
const scaleDepth = useScaleDepth(groupId);
|
|
28
|
+
const animatedStyle = useScaleAnimatedStyle(scaleDepth, scaleConfig);
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<Animated.View style={[styles.container, animatedStyle]}>
|
|
32
|
+
{children}
|
|
33
|
+
</Animated.View>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const styles = StyleSheet.create({
|
|
38
|
+
container: {
|
|
39
|
+
flex: 1,
|
|
40
|
+
},
|
|
41
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { makeMutable, type SharedValue } from 'react-native-reanimated';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Registry for shared animated values per sheet.
|
|
5
|
+
* This allows backdrop to access the animatedIndex from the bottom sheet.
|
|
6
|
+
*/
|
|
7
|
+
const animatedIndexRegistry = new Map<string, SharedValue<number>>();
|
|
8
|
+
|
|
9
|
+
export function getAnimatedIndex(sheetId: string): SharedValue<number> {
|
|
10
|
+
let animatedIndex = animatedIndexRegistry.get(sheetId);
|
|
11
|
+
|
|
12
|
+
if (!animatedIndex) {
|
|
13
|
+
animatedIndex = makeMutable(-1);
|
|
14
|
+
animatedIndexRegistry.set(sheetId, animatedIndex);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return animatedIndex;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function cleanupAnimatedIndex(sheetId: string): void {
|
|
21
|
+
animatedIndexRegistry.delete(sheetId);
|
|
22
|
+
}
|
package/src/bottomSheet.store.ts
CHANGED
|
@@ -30,136 +30,136 @@ interface BottomSheetStoreActions {
|
|
|
30
30
|
clearAll(): void;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
export
|
|
34
|
-
subscribeWithSelector<BottomSheetStoreState & BottomSheetStoreActions>(
|
|
35
|
-
(set) => ({
|
|
36
|
-
sheetsById: {},
|
|
37
|
-
stackOrder: [],
|
|
38
|
-
|
|
39
|
-
push: (sheet) =>
|
|
40
|
-
set((state) => {
|
|
41
|
-
if (state.sheetsById[sheet.id]) {
|
|
42
|
-
return state;
|
|
43
|
-
}
|
|
44
|
-
return {
|
|
45
|
-
sheetsById: {
|
|
46
|
-
...state.sheetsById,
|
|
47
|
-
[sheet.id]: { ...sheet, status: 'opening' },
|
|
48
|
-
},
|
|
49
|
-
stackOrder: [...state.stackOrder, sheet.id],
|
|
50
|
-
};
|
|
51
|
-
}),
|
|
52
|
-
|
|
53
|
-
switch: (sheet) =>
|
|
54
|
-
set((state) => {
|
|
55
|
-
if (state.sheetsById[sheet.id]) {
|
|
56
|
-
return state;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const newSheetsById = { ...state.sheetsById };
|
|
60
|
-
const topId = state.stackOrder[state.stackOrder.length - 1];
|
|
61
|
-
|
|
62
|
-
if (topId && newSheetsById[topId]) {
|
|
63
|
-
newSheetsById[topId] = {
|
|
64
|
-
...newSheetsById[topId],
|
|
65
|
-
status: 'hidden',
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
newSheetsById[sheet.id] = { ...sheet, status: 'opening' };
|
|
70
|
-
|
|
71
|
-
return {
|
|
72
|
-
sheetsById: newSheetsById,
|
|
73
|
-
stackOrder: [...state.stackOrder, sheet.id],
|
|
74
|
-
};
|
|
75
|
-
}),
|
|
76
|
-
|
|
77
|
-
replace: (sheet) =>
|
|
78
|
-
set((state) => {
|
|
79
|
-
if (state.sheetsById[sheet.id]) {
|
|
80
|
-
return state;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const newSheetsById = { ...state.sheetsById };
|
|
84
|
-
const topId = state.stackOrder[state.stackOrder.length - 1];
|
|
85
|
-
|
|
86
|
-
if (topId && newSheetsById[topId]) {
|
|
87
|
-
newSheetsById[topId] = {
|
|
88
|
-
...newSheetsById[topId],
|
|
89
|
-
status: 'closing',
|
|
90
|
-
};
|
|
91
|
-
}
|
|
33
|
+
export type BottomSheetStore = BottomSheetStoreState & BottomSheetStoreActions;
|
|
92
34
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
35
|
+
export const useBottomSheetStore = create(
|
|
36
|
+
subscribeWithSelector<BottomSheetStore>((set) => ({
|
|
37
|
+
sheetsById: {},
|
|
38
|
+
stackOrder: [],
|
|
39
|
+
|
|
40
|
+
push: (sheet) =>
|
|
41
|
+
set((state) => {
|
|
42
|
+
if (state.sheetsById[sheet.id]) {
|
|
43
|
+
return state;
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
sheetsById: {
|
|
47
|
+
...state.sheetsById,
|
|
48
|
+
[sheet.id]: { ...sheet, status: 'opening' },
|
|
49
|
+
},
|
|
50
|
+
stackOrder: [...state.stackOrder, sheet.id],
|
|
51
|
+
};
|
|
52
|
+
}),
|
|
53
|
+
|
|
54
|
+
switch: (sheet) =>
|
|
55
|
+
set((state) => {
|
|
56
|
+
if (state.sheetsById[sheet.id]) {
|
|
57
|
+
return state;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const newSheetsById = { ...state.sheetsById };
|
|
61
|
+
const topId = state.stackOrder[state.stackOrder.length - 1];
|
|
62
|
+
|
|
63
|
+
if (topId && newSheetsById[topId]) {
|
|
64
|
+
newSheetsById[topId] = {
|
|
65
|
+
...newSheetsById[topId],
|
|
66
|
+
status: 'hidden',
|
|
112
67
|
};
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
startClosing: (id) =>
|
|
116
|
-
set((state) => {
|
|
117
|
-
const sheet = state.sheetsById[id];
|
|
118
|
-
if (!sheet || sheet.status === 'hidden') {
|
|
119
|
-
return state;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
const newSheetsById = { ...state.sheetsById };
|
|
123
|
-
newSheetsById[id] = { ...sheet, status: 'closing' };
|
|
68
|
+
}
|
|
124
69
|
|
|
125
|
-
|
|
126
|
-
const belowId = state.stackOrder[index - 1];
|
|
127
|
-
const belowSheet = belowId ? newSheetsById[belowId] : undefined;
|
|
70
|
+
newSheetsById[sheet.id] = { ...sheet, status: 'opening' };
|
|
128
71
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
72
|
+
return {
|
|
73
|
+
sheetsById: newSheetsById,
|
|
74
|
+
stackOrder: [...state.stackOrder, sheet.id],
|
|
75
|
+
};
|
|
76
|
+
}),
|
|
132
77
|
|
|
133
|
-
|
|
134
|
-
|
|
78
|
+
replace: (sheet) =>
|
|
79
|
+
set((state) => {
|
|
80
|
+
if (state.sheetsById[sheet.id]) {
|
|
81
|
+
return state;
|
|
82
|
+
}
|
|
135
83
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
if (!state.sheetsById[id]) {
|
|
139
|
-
return state;
|
|
140
|
-
}
|
|
84
|
+
const newSheetsById = { ...state.sheetsById };
|
|
85
|
+
const topId = state.stackOrder[state.stackOrder.length - 1];
|
|
141
86
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
(sheetId) => sheetId !== id
|
|
147
|
-
);
|
|
148
|
-
|
|
149
|
-
const topId = newStackOrder[newStackOrder.length - 1];
|
|
150
|
-
const topSheet = topId ? newSheetsById[topId] : undefined;
|
|
151
|
-
|
|
152
|
-
if (topId && topSheet && topSheet.status === 'hidden') {
|
|
153
|
-
newSheetsById[topId] = { ...topSheet, status: 'opening' };
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
return {
|
|
157
|
-
sheetsById: newSheetsById,
|
|
158
|
-
stackOrder: newStackOrder,
|
|
87
|
+
if (topId && newSheetsById[topId]) {
|
|
88
|
+
newSheetsById[topId] = {
|
|
89
|
+
...newSheetsById[topId],
|
|
90
|
+
status: 'closing',
|
|
159
91
|
};
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
newSheetsById[sheet.id] = { ...sheet, status: 'opening' };
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
sheetsById: newSheetsById,
|
|
98
|
+
stackOrder: [...state.stackOrder, sheet.id],
|
|
99
|
+
};
|
|
100
|
+
}),
|
|
101
|
+
|
|
102
|
+
markOpen: (id) =>
|
|
103
|
+
set((state) => {
|
|
104
|
+
const sheet = state.sheetsById[id];
|
|
105
|
+
if (!sheet) {
|
|
106
|
+
return state;
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
sheetsById: {
|
|
110
|
+
...state.sheetsById,
|
|
111
|
+
[id]: { ...sheet, status: 'open' },
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
}),
|
|
115
|
+
|
|
116
|
+
startClosing: (id) =>
|
|
117
|
+
set((state) => {
|
|
118
|
+
const sheet = state.sheetsById[id];
|
|
119
|
+
if (!sheet || sheet.status === 'hidden') {
|
|
120
|
+
return state;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const newSheetsById = { ...state.sheetsById };
|
|
124
|
+
newSheetsById[id] = { ...sheet, status: 'closing' };
|
|
125
|
+
|
|
126
|
+
const index = state.stackOrder.indexOf(id);
|
|
127
|
+
const belowId = state.stackOrder[index - 1];
|
|
128
|
+
const belowSheet = belowId ? newSheetsById[belowId] : undefined;
|
|
129
|
+
|
|
130
|
+
if (belowId && belowSheet && belowSheet.status === 'hidden') {
|
|
131
|
+
newSheetsById[belowId] = { ...belowSheet, status: 'opening' };
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return { sheetsById: newSheetsById };
|
|
135
|
+
}),
|
|
136
|
+
|
|
137
|
+
finishClosing: (id) =>
|
|
138
|
+
set((state) => {
|
|
139
|
+
if (!state.sheetsById[id]) {
|
|
140
|
+
return state;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const newSheetsById = { ...state.sheetsById };
|
|
144
|
+
delete newSheetsById[id];
|
|
145
|
+
|
|
146
|
+
const newStackOrder = state.stackOrder.filter(
|
|
147
|
+
(sheetId) => sheetId !== id
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
const topId = newStackOrder[newStackOrder.length - 1];
|
|
151
|
+
const topSheet = topId ? newSheetsById[topId] : undefined;
|
|
152
|
+
|
|
153
|
+
if (topId && topSheet && topSheet.status === 'hidden') {
|
|
154
|
+
newSheetsById[topId] = { ...topSheet, status: 'opening' };
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return {
|
|
158
|
+
sheetsById: newSheetsById,
|
|
159
|
+
stackOrder: newStackOrder,
|
|
160
|
+
};
|
|
161
|
+
}),
|
|
162
|
+
|
|
163
|
+
clearAll: () => set(() => ({ sheetsById: {}, stackOrder: [] })),
|
|
164
|
+
}))
|
|
165
165
|
);
|
|
@@ -16,19 +16,18 @@ export function initBottomSheetCoordinator(groupId: string) {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
const ref = sheetRefs[id]?.current;
|
|
19
|
-
if (!ref) {
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
19
|
|
|
23
20
|
switch (status) {
|
|
24
21
|
case 'opening':
|
|
25
|
-
|
|
22
|
+
requestAnimationFrame(() => {
|
|
23
|
+
sheetRefs[id]?.current?.expand();
|
|
24
|
+
});
|
|
26
25
|
break;
|
|
27
26
|
case 'hidden':
|
|
28
|
-
ref.close();
|
|
27
|
+
if (ref) ref.close();
|
|
29
28
|
break;
|
|
30
29
|
case 'closing':
|
|
31
|
-
ref.close();
|
|
30
|
+
if (ref) ref.close();
|
|
32
31
|
break;
|
|
33
32
|
}
|
|
34
33
|
});
|
package/src/index.tsx
CHANGED
|
@@ -3,7 +3,5 @@ export { BottomSheetManagerProvider } from './BottomSheetManager.provider';
|
|
|
3
3
|
export { useBottomSheetManager } from './useBottomSheetManager';
|
|
4
4
|
export { useBottomSheetState } from './useBottomSheetState';
|
|
5
5
|
export { BottomSheetManaged } from './BottomSheetManaged';
|
|
6
|
-
export {
|
|
7
|
-
|
|
8
|
-
type ScaleBackgroundConfig,
|
|
9
|
-
} from './ScaleBackgroundWrapper';
|
|
6
|
+
export { BottomSheetScaleView } from './BottomSheetScaleView';
|
|
7
|
+
export { type ScaleConfig } from './useScaleAnimation';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from 'react';
|
|
2
2
|
|
|
3
3
|
import { useBottomSheetStore, type OpenMode } from './bottomSheet.store';
|
|
4
4
|
import { useMaybeBottomSheetManagerContext } from './BottomSheetManager.provider';
|
|
@@ -26,62 +26,51 @@ export const useBottomSheetManager = () => {
|
|
|
26
26
|
shallow
|
|
27
27
|
);
|
|
28
28
|
|
|
29
|
-
const openBottomSheet =
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
options.groupId || bottomSheetManagerContext?.groupId || 'default';
|
|
29
|
+
const openBottomSheet = (
|
|
30
|
+
content: React.ReactElement,
|
|
31
|
+
options: {
|
|
32
|
+
id?: string;
|
|
33
|
+
groupId?: string;
|
|
34
|
+
mode?: OpenMode;
|
|
35
|
+
scaleBackground?: boolean;
|
|
36
|
+
} = {}
|
|
37
|
+
) => {
|
|
38
|
+
const groupId =
|
|
39
|
+
options.groupId || bottomSheetManagerContext?.groupId || 'default';
|
|
41
40
|
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
const id = options.id || Math.random().toString(36);
|
|
42
|
+
const ref = React.createRef<BottomSheetMethods>();
|
|
44
43
|
|
|
45
|
-
|
|
44
|
+
sheetRefs[id] = ref;
|
|
46
45
|
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
// @ts-ignore
|
|
47
|
+
const contentWithRef = React.cloneElement(content, { ref });
|
|
49
48
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
49
|
+
const sheetData = {
|
|
50
|
+
id,
|
|
51
|
+
groupId,
|
|
52
|
+
content: contentWithRef,
|
|
53
|
+
scaleBackground: options.scaleBackground,
|
|
54
|
+
};
|
|
56
55
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
56
|
+
if (options.mode === 'replace') {
|
|
57
|
+
replaceBottomSheet(sheetData);
|
|
58
|
+
} else if (options.mode === 'switch') {
|
|
59
|
+
switchBottomSheet(sheetData);
|
|
60
|
+
} else {
|
|
61
|
+
pushBottomSheet(sheetData);
|
|
62
|
+
}
|
|
64
63
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
[
|
|
68
|
-
bottomSheetManagerContext?.groupId,
|
|
69
|
-
pushBottomSheet,
|
|
70
|
-
replaceBottomSheet,
|
|
71
|
-
switchBottomSheet,
|
|
72
|
-
]
|
|
73
|
-
);
|
|
64
|
+
return id;
|
|
65
|
+
};
|
|
74
66
|
|
|
75
|
-
const close =
|
|
76
|
-
(id
|
|
77
|
-
|
|
78
|
-
},
|
|
79
|
-
[startClosing]
|
|
80
|
-
);
|
|
67
|
+
const close = (id: string) => {
|
|
68
|
+
startClosing(id);
|
|
69
|
+
};
|
|
81
70
|
|
|
82
|
-
const clearAll =
|
|
71
|
+
const clearAll = () => {
|
|
83
72
|
storeClearAll();
|
|
84
|
-
}
|
|
73
|
+
};
|
|
85
74
|
|
|
86
75
|
return {
|
|
87
76
|
clearAll,
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { useCallback } from 'react';
|
|
2
1
|
import { useMaybeBottomSheetContext } from './BottomSheet.context';
|
|
3
2
|
import {
|
|
4
3
|
useBottomSheetStore,
|
|
@@ -13,7 +12,7 @@ export function useBottomSheetState(): {
|
|
|
13
12
|
const context = useMaybeBottomSheetContext();
|
|
14
13
|
|
|
15
14
|
const bottomSheetState = useBottomSheetStore(
|
|
16
|
-
|
|
15
|
+
(state) => state.sheetsById[context?.id!]
|
|
17
16
|
);
|
|
18
17
|
|
|
19
18
|
const startClosing = useBottomSheetStore((state) => state.startClosing);
|
|
@@ -24,10 +23,7 @@ export function useBottomSheetState(): {
|
|
|
24
23
|
);
|
|
25
24
|
}
|
|
26
25
|
|
|
27
|
-
const close =
|
|
28
|
-
() => startClosing(bottomSheetState.id),
|
|
29
|
-
[bottomSheetState.id, startClosing]
|
|
30
|
-
);
|
|
26
|
+
const close = () => startClosing(bottomSheetState.id);
|
|
31
27
|
|
|
32
28
|
return {
|
|
33
29
|
bottomSheetState,
|