@oxyhq/services 22.8.6 → 22.9.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.
- package/lib/commonjs/ui/components/OxyAccountDialog.js +30 -39
- package/lib/commonjs/ui/components/OxyAccountDialog.js.map +1 -1
- package/lib/commonjs/ui/components/OxyProvider.js +9 -29
- package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
- package/lib/commonjs/ui/components/SurfaceScreen.js +146 -0
- package/lib/commonjs/ui/components/SurfaceScreen.js.map +1 -0
- package/lib/commonjs/ui/components/fileManagement/UploadPreview.js +3 -3
- package/lib/commonjs/ui/components/fileManagement/UploadPreview.js.map +1 -1
- package/lib/commonjs/ui/context/OxyContext.js +32 -1
- package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
- package/lib/commonjs/ui/navigation/bottomSheetManager.js +38 -56
- package/lib/commonjs/ui/navigation/bottomSheetManager.js.map +1 -1
- package/lib/commonjs/ui/navigation/routes.js +7 -57
- package/lib/commonjs/ui/navigation/routes.js.map +1 -1
- package/lib/commonjs/ui/navigation/surfaceNavStack.js +98 -0
- package/lib/commonjs/ui/navigation/surfaceNavStack.js.map +1 -0
- package/lib/commonjs/ui/navigation/surfaceRegistry.js +108 -0
- package/lib/commonjs/ui/navigation/surfaceRegistry.js.map +1 -0
- package/lib/commonjs/ui/navigation/surfaces.js +219 -0
- package/lib/commonjs/ui/navigation/surfaces.js.map +1 -0
- package/lib/commonjs/ui/screens/FileManagementScreen.js +8 -1
- package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/fileManagement/PhotoPickerSection.js +60 -3
- package/lib/commonjs/ui/screens/fileManagement/PhotoPickerSection.js.map +1 -1
- package/lib/commonjs/ui/screens/fileManagement/hooks/useFileUploadState.js +14 -17
- package/lib/commonjs/ui/screens/fileManagement/hooks/useFileUploadState.js.map +1 -1
- package/lib/commonjs/ui/screens/fileManagement/shared.js +13 -1
- package/lib/commonjs/ui/screens/fileManagement/shared.js.map +1 -1
- package/lib/commonjs/ui/types/surfaceScreen.js +6 -0
- package/lib/commonjs/ui/types/surfaceScreen.js.map +1 -0
- package/lib/module/ui/components/OxyAccountDialog.js +31 -40
- package/lib/module/ui/components/OxyAccountDialog.js.map +1 -1
- package/lib/module/ui/components/OxyProvider.js +10 -30
- package/lib/module/ui/components/OxyProvider.js.map +1 -1
- package/lib/module/ui/components/SurfaceScreen.js +141 -0
- package/lib/module/ui/components/SurfaceScreen.js.map +1 -0
- package/lib/module/ui/components/fileManagement/UploadPreview.js +3 -3
- package/lib/module/ui/components/fileManagement/UploadPreview.js.map +1 -1
- package/lib/module/ui/context/OxyContext.js +32 -1
- package/lib/module/ui/context/OxyContext.js.map +1 -1
- package/lib/module/ui/navigation/bottomSheetManager.js +37 -53
- package/lib/module/ui/navigation/bottomSheetManager.js.map +1 -1
- package/lib/module/ui/navigation/routes.js +6 -56
- package/lib/module/ui/navigation/routes.js.map +1 -1
- package/lib/module/ui/navigation/surfaceNavStack.js +95 -0
- package/lib/module/ui/navigation/surfaceNavStack.js.map +1 -0
- package/lib/module/ui/navigation/surfaceRegistry.js +102 -0
- package/lib/module/ui/navigation/surfaceRegistry.js.map +1 -0
- package/lib/module/ui/navigation/surfaces.js +207 -0
- package/lib/module/ui/navigation/surfaces.js.map +1 -0
- package/lib/module/ui/screens/FileManagementScreen.js +8 -1
- package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/module/ui/screens/fileManagement/PhotoPickerSection.js +60 -3
- package/lib/module/ui/screens/fileManagement/PhotoPickerSection.js.map +1 -1
- package/lib/module/ui/screens/fileManagement/hooks/useFileUploadState.js +14 -18
- package/lib/module/ui/screens/fileManagement/hooks/useFileUploadState.js.map +1 -1
- package/lib/module/ui/screens/fileManagement/shared.js +12 -0
- package/lib/module/ui/screens/fileManagement/shared.js.map +1 -1
- package/lib/module/ui/types/surfaceScreen.js +4 -0
- package/lib/module/ui/types/surfaceScreen.js.map +1 -0
- package/lib/typescript/commonjs/ui/components/OxyAccountDialog.d.ts +29 -27
- package/lib/typescript/commonjs/ui/components/OxyAccountDialog.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/OxyProvider.d.ts +3 -2
- package/lib/typescript/commonjs/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/SurfaceScreen.d.ts +24 -0
- package/lib/typescript/commonjs/ui/components/SurfaceScreen.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/fileManagement/UploadPreview.d.ts +3 -10
- package/lib/typescript/commonjs/ui/components/fileManagement/UploadPreview.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/navigation/bottomSheetManager.d.ts +24 -16
- package/lib/typescript/commonjs/ui/navigation/bottomSheetManager.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/navigation/routes.d.ts +2 -60
- package/lib/typescript/commonjs/ui/navigation/routes.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/navigation/surfaceNavStack.d.ts +51 -0
- package/lib/typescript/commonjs/ui/navigation/surfaceNavStack.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/navigation/surfaceRegistry.d.ts +117 -0
- package/lib/typescript/commonjs/ui/navigation/surfaceRegistry.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/navigation/surfaces.d.ts +79 -0
- package/lib/typescript/commonjs/ui/navigation/surfaces.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/screens/FileManagementScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/fileManagement/PhotoPickerSection.d.ts +7 -0
- package/lib/typescript/commonjs/ui/screens/fileManagement/PhotoPickerSection.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/fileManagement/hooks/useFileUploadState.d.ts +1 -1
- package/lib/typescript/commonjs/ui/screens/fileManagement/hooks/useFileUploadState.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/fileManagement/shared.d.ts +4 -0
- package/lib/typescript/commonjs/ui/screens/fileManagement/shared.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/types/surfaceScreen.d.ts +38 -0
- package/lib/typescript/commonjs/ui/types/surfaceScreen.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/OxyAccountDialog.d.ts +29 -27
- package/lib/typescript/module/ui/components/OxyAccountDialog.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/OxyProvider.d.ts +3 -2
- package/lib/typescript/module/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/SurfaceScreen.d.ts +24 -0
- package/lib/typescript/module/ui/components/SurfaceScreen.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/fileManagement/UploadPreview.d.ts +3 -10
- package/lib/typescript/module/ui/components/fileManagement/UploadPreview.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/module/ui/navigation/bottomSheetManager.d.ts +24 -16
- package/lib/typescript/module/ui/navigation/bottomSheetManager.d.ts.map +1 -1
- package/lib/typescript/module/ui/navigation/routes.d.ts +2 -60
- package/lib/typescript/module/ui/navigation/routes.d.ts.map +1 -1
- package/lib/typescript/module/ui/navigation/surfaceNavStack.d.ts +51 -0
- package/lib/typescript/module/ui/navigation/surfaceNavStack.d.ts.map +1 -0
- package/lib/typescript/module/ui/navigation/surfaceRegistry.d.ts +117 -0
- package/lib/typescript/module/ui/navigation/surfaceRegistry.d.ts.map +1 -0
- package/lib/typescript/module/ui/navigation/surfaces.d.ts +79 -0
- package/lib/typescript/module/ui/navigation/surfaces.d.ts.map +1 -0
- package/lib/typescript/module/ui/screens/FileManagementScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/fileManagement/PhotoPickerSection.d.ts +7 -0
- package/lib/typescript/module/ui/screens/fileManagement/PhotoPickerSection.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/fileManagement/hooks/useFileUploadState.d.ts +1 -1
- package/lib/typescript/module/ui/screens/fileManagement/hooks/useFileUploadState.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/fileManagement/shared.d.ts +4 -0
- package/lib/typescript/module/ui/screens/fileManagement/shared.d.ts.map +1 -1
- package/lib/typescript/module/ui/types/surfaceScreen.d.ts +38 -0
- package/lib/typescript/module/ui/types/surfaceScreen.d.ts.map +1 -0
- package/package.json +2 -2
- package/src/ui/components/OxyAccountDialog.tsx +32 -38
- package/src/ui/components/OxyProvider.tsx +12 -34
- package/src/ui/components/SurfaceScreen.tsx +166 -0
- package/src/ui/components/fileManagement/UploadPreview.tsx +8 -16
- package/src/ui/context/OxyContext.tsx +27 -1
- package/src/ui/navigation/__tests__/getSurfaceConfig.test.ts +39 -0
- package/src/ui/navigation/bottomSheetManager.ts +46 -73
- package/src/ui/navigation/routes.ts +7 -106
- package/src/ui/navigation/surfaceNavStack.ts +110 -0
- package/src/ui/navigation/surfaceRegistry.ts +174 -0
- package/src/ui/navigation/surfaces.ts +244 -0
- package/src/ui/screens/FileManagementScreen.tsx +8 -1
- package/src/ui/screens/fileManagement/PhotoPickerSection.tsx +69 -7
- package/src/ui/screens/fileManagement/hooks/useFileUploadState.ts +16 -18
- package/src/ui/screens/fileManagement/shared.ts +23 -0
- package/src/ui/types/surfaceScreen.ts +38 -0
- package/lib/commonjs/ui/components/BottomSheet.js +0 -49
- package/lib/commonjs/ui/components/BottomSheet.js.map +0 -1
- package/lib/commonjs/ui/components/BottomSheetRouter.js +0 -298
- package/lib/commonjs/ui/components/BottomSheetRouter.js.map +0 -1
- package/lib/module/ui/components/BottomSheet.js +0 -45
- package/lib/module/ui/components/BottomSheet.js.map +0 -1
- package/lib/module/ui/components/BottomSheetRouter.js +0 -292
- package/lib/module/ui/components/BottomSheetRouter.js.map +0 -1
- package/lib/typescript/commonjs/ui/components/BottomSheet.d.ts +0 -29
- package/lib/typescript/commonjs/ui/components/BottomSheet.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/components/BottomSheetRouter.d.ts +0 -9
- package/lib/typescript/commonjs/ui/components/BottomSheetRouter.d.ts.map +0 -1
- package/lib/typescript/module/ui/components/BottomSheet.d.ts +0 -29
- package/lib/typescript/module/ui/components/BottomSheet.d.ts.map +0 -1
- package/lib/typescript/module/ui/components/BottomSheetRouter.d.ts +0 -9
- package/lib/typescript/module/ui/components/BottomSheetRouter.d.ts.map +0 -1
- package/src/ui/components/BottomSheet.tsx +0 -48
- package/src/ui/components/BottomSheetRouter.tsx +0 -310
- package/src/ui/navigation/__tests__/getSheetConfig.test.ts +0 -36
|
@@ -1,310 +0,0 @@
|
|
|
1
|
-
import React, { useRef, useEffect, useCallback, useMemo, type ErrorInfo } from 'react';
|
|
2
|
-
import { BackHandler, Platform, View, StyleSheet, Text, type StyleProp, type ViewStyle } from 'react-native';
|
|
3
|
-
import { useStore } from 'zustand';
|
|
4
|
-
import type { RouteName } from '../navigation/routes';
|
|
5
|
-
import { getScreenComponent, getSheetConfig, isValidRoute } from '../navigation/routes';
|
|
6
|
-
import type { BaseScreenProps } from '../types/navigation';
|
|
7
|
-
import { useTheme } from '@oxyhq/bloom/theme';
|
|
8
|
-
import { Dialog } from '@oxyhq/bloom/dialog';
|
|
9
|
-
import BottomSheet, { type BottomSheetRef } from './BottomSheet';
|
|
10
|
-
import {
|
|
11
|
-
bottomSheetStore,
|
|
12
|
-
getState,
|
|
13
|
-
showBottomSheet,
|
|
14
|
-
closeBottomSheet,
|
|
15
|
-
goBack,
|
|
16
|
-
updateState,
|
|
17
|
-
} from '../navigation/bottomSheetManager';
|
|
18
|
-
|
|
19
|
-
/** Error boundary to catch screen rendering failures (e.g. lazy require() throws) */
|
|
20
|
-
interface ScreenErrorBoundaryState {
|
|
21
|
-
error: Error | null;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
class ScreenErrorBoundary extends React.Component<
|
|
25
|
-
{ screenName: string; children: React.ReactNode },
|
|
26
|
-
ScreenErrorBoundaryState
|
|
27
|
-
> {
|
|
28
|
-
state: ScreenErrorBoundaryState = { error: null };
|
|
29
|
-
|
|
30
|
-
static getDerivedStateFromError(error: Error): ScreenErrorBoundaryState {
|
|
31
|
-
return { error };
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
componentDidCatch(error: Error, info: ErrorInfo): void {
|
|
35
|
-
if (__DEV__) {
|
|
36
|
-
console.error(
|
|
37
|
-
`[BottomSheetRouter] Screen "${this.props.screenName}" crashed:`,
|
|
38
|
-
error,
|
|
39
|
-
info.componentStack,
|
|
40
|
-
);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
componentDidUpdate(prevProps: { screenName: string }): void {
|
|
45
|
-
if (prevProps.screenName !== this.props.screenName && this.state.error) {
|
|
46
|
-
this.setState({ error: null });
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
render(): React.ReactNode {
|
|
51
|
-
if (this.state.error) {
|
|
52
|
-
return (
|
|
53
|
-
<View style={errorStyles.container}>
|
|
54
|
-
<Text style={errorStyles.title}>Something went wrong</Text>
|
|
55
|
-
{__DEV__ && (
|
|
56
|
-
<Text style={errorStyles.message}>{this.state.error.message}</Text>
|
|
57
|
-
)}
|
|
58
|
-
</View>
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
return this.props.children;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const errorStyles = StyleSheet.create({
|
|
66
|
-
container: { flex: 1, alignItems: 'center', justifyContent: 'center', padding: 24 },
|
|
67
|
-
title: { fontSize: 16, fontWeight: '600', marginBottom: 8 },
|
|
68
|
-
message: { fontSize: 13, textAlign: 'center' },
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Responsive placement for `presentation: 'dialog'` routes: a bottom-sheet on
|
|
73
|
-
* narrow viewports, a centered card at `md+` (≥768dp). Module-scoped so the
|
|
74
|
-
* object identity is stable across renders (Bloom's placement resolver memoizes
|
|
75
|
-
* on it). PhotoPickerSection keys its center-vs-bottom layout off the SAME `md`
|
|
76
|
-
* breakpoint — keep the two in sync if this map changes.
|
|
77
|
-
*/
|
|
78
|
-
const DIALOG_PLACEMENT = { base: 'bottom', md: 'center' } as const;
|
|
79
|
-
|
|
80
|
-
export interface BottomSheetRouterProps {
|
|
81
|
-
onScreenChange?: (screen: RouteName | null) => void;
|
|
82
|
-
onDismiss?: () => void;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* BottomSheetRouter - Navigation container for bottom sheet screens
|
|
87
|
-
*/
|
|
88
|
-
const BottomSheetRouter: React.FC<BottomSheetRouterProps> = ({ onScreenChange, onDismiss }) => {
|
|
89
|
-
const sheetRef = useRef<BottomSheetRef>(null);
|
|
90
|
-
const theme = useTheme();
|
|
91
|
-
const prevScreenRef = useRef<RouteName | null>(null);
|
|
92
|
-
|
|
93
|
-
const { currentScreen, screenProps, currentStep, isOpen } = useStore(bottomSheetStore);
|
|
94
|
-
|
|
95
|
-
const ScreenComponent = useMemo(() => {
|
|
96
|
-
if (!currentScreen) return null;
|
|
97
|
-
const component = getScreenComponent(currentScreen);
|
|
98
|
-
if (__DEV__ && !component) {
|
|
99
|
-
console.error(
|
|
100
|
-
`[BottomSheetRouter] getScreenComponent("${currentScreen}") returned undefined — the screen's lazy require() likely failed.`,
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
return component ?? null;
|
|
104
|
-
}, [currentScreen]);
|
|
105
|
-
|
|
106
|
-
// Route-level sheet config (which surface hosts the route, whether the sheet
|
|
107
|
-
// provides its own ScrollView, etc.). Computed early so the visibility
|
|
108
|
-
// effect can gate the in-tree sheet on the resolved presentation.
|
|
109
|
-
const sheetConfig = useMemo(
|
|
110
|
-
() => getSheetConfig(currentScreen, screenProps),
|
|
111
|
-
[currentScreen, screenProps],
|
|
112
|
-
);
|
|
113
|
-
const isDialogPresentation = sheetConfig.presentation === 'dialog';
|
|
114
|
-
|
|
115
|
-
// Notify screen changes
|
|
116
|
-
useEffect(() => {
|
|
117
|
-
if (prevScreenRef.current !== currentScreen) {
|
|
118
|
-
onScreenChange?.(currentScreen);
|
|
119
|
-
prevScreenRef.current = currentScreen;
|
|
120
|
-
}
|
|
121
|
-
}, [currentScreen, onScreenChange]);
|
|
122
|
-
|
|
123
|
-
// Control visibility. The in-tree BottomSheet only ever presents for
|
|
124
|
-
// 'sheet'-presentation routes — 'dialog' routes render in the Bloom
|
|
125
|
-
// `<Dialog>` below, so the sheet stays dismissed for them (both surfaces
|
|
126
|
-
// remain mounted, so the pick→crop dialog→sheet handoff has no unmount jank).
|
|
127
|
-
useEffect(() => {
|
|
128
|
-
if (!sheetRef.current) return;
|
|
129
|
-
|
|
130
|
-
if (isOpen && !isDialogPresentation) {
|
|
131
|
-
sheetRef.current.present();
|
|
132
|
-
} else {
|
|
133
|
-
sheetRef.current.dismiss();
|
|
134
|
-
}
|
|
135
|
-
}, [isOpen, isDialogPresentation]);
|
|
136
|
-
|
|
137
|
-
// Android back button
|
|
138
|
-
useEffect(() => {
|
|
139
|
-
if (!isOpen) return;
|
|
140
|
-
if (Platform.OS !== 'android') return;
|
|
141
|
-
const handler = BackHandler.addEventListener('hardwareBackPress', () => {
|
|
142
|
-
handleGoBack();
|
|
143
|
-
return true;
|
|
144
|
-
});
|
|
145
|
-
return () => handler.remove();
|
|
146
|
-
}, [isOpen]);
|
|
147
|
-
|
|
148
|
-
const navigate = useCallback((screen: RouteName, props?: Record<string, unknown>) => {
|
|
149
|
-
if (!isValidRoute(screen)) {
|
|
150
|
-
if (__DEV__) console.warn(`[BottomSheetRouter] Invalid route: ${screen}`);
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
showBottomSheet({ screen, props });
|
|
154
|
-
}, []);
|
|
155
|
-
|
|
156
|
-
const handleGoBack = useCallback(() => {
|
|
157
|
-
const state = getState();
|
|
158
|
-
|
|
159
|
-
// Try history first
|
|
160
|
-
if (state.history.length > 0) {
|
|
161
|
-
goBack();
|
|
162
|
-
return true;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// Try step back
|
|
166
|
-
const step = state.currentStep ?? 0;
|
|
167
|
-
if (step > 0) {
|
|
168
|
-
updateState({
|
|
169
|
-
currentStep: step - 1,
|
|
170
|
-
screenProps: { ...state.screenProps, initialStep: step - 1 },
|
|
171
|
-
});
|
|
172
|
-
return true;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// Close
|
|
176
|
-
closeBottomSheet();
|
|
177
|
-
return true;
|
|
178
|
-
}, []);
|
|
179
|
-
|
|
180
|
-
const canDismiss = useCallback((): boolean => {
|
|
181
|
-
const state = getState();
|
|
182
|
-
if (state.history.length > 0) return false;
|
|
183
|
-
const step = state.currentStep ?? 0;
|
|
184
|
-
return step <= 0;
|
|
185
|
-
}, []);
|
|
186
|
-
|
|
187
|
-
const handleDismissAttempt = useCallback((): boolean => {
|
|
188
|
-
if (!canDismiss()) {
|
|
189
|
-
handleGoBack();
|
|
190
|
-
return false;
|
|
191
|
-
}
|
|
192
|
-
return true;
|
|
193
|
-
}, [canDismiss, handleGoBack]);
|
|
194
|
-
|
|
195
|
-
const handleDismiss = useCallback(() => {
|
|
196
|
-
closeBottomSheet();
|
|
197
|
-
onDismiss?.();
|
|
198
|
-
}, [onDismiss]);
|
|
199
|
-
|
|
200
|
-
const handleStepChange = useCallback((step: number) => {
|
|
201
|
-
const state = getState();
|
|
202
|
-
updateState({
|
|
203
|
-
currentStep: step,
|
|
204
|
-
screenProps: { ...state.screenProps, initialStep: step },
|
|
205
|
-
});
|
|
206
|
-
}, []);
|
|
207
|
-
|
|
208
|
-
const scrollTo = useCallback((y: number, animated?: boolean) => {
|
|
209
|
-
sheetRef.current?.scrollTo(y, animated);
|
|
210
|
-
}, []);
|
|
211
|
-
|
|
212
|
-
const renderBackground = useCallback(
|
|
213
|
-
(props: { style?: StyleProp<ViewStyle> }) => (
|
|
214
|
-
<View style={[styles.background, { backgroundColor: theme.colors.background }, props.style]} />
|
|
215
|
-
),
|
|
216
|
-
[theme.colors.background]
|
|
217
|
-
);
|
|
218
|
-
|
|
219
|
-
const screenPropsValue = useMemo((): BaseScreenProps & { scrollTo: typeof scrollTo } => {
|
|
220
|
-
const { initialStep: _, ...rest } = screenProps;
|
|
221
|
-
return {
|
|
222
|
-
navigate,
|
|
223
|
-
goBack: handleGoBack,
|
|
224
|
-
onClose: closeBottomSheet,
|
|
225
|
-
onAuthenticated: closeBottomSheet,
|
|
226
|
-
theme: theme.mode,
|
|
227
|
-
currentScreen: currentScreen ?? undefined,
|
|
228
|
-
initialStep: currentStep ?? (screenProps?.initialStep as number | undefined),
|
|
229
|
-
onStepChange: handleStepChange,
|
|
230
|
-
scrollTo,
|
|
231
|
-
...rest,
|
|
232
|
-
};
|
|
233
|
-
}, [navigate, handleGoBack, theme.mode, currentScreen, currentStep, screenProps, handleStepChange, scrollTo]);
|
|
234
|
-
|
|
235
|
-
// The active screen, wrapped in its error boundary. Routed into EXACTLY ONE
|
|
236
|
-
// surface (the in-tree sheet OR the Dialog) based on the resolved
|
|
237
|
-
// presentation, so it never double-mounts.
|
|
238
|
-
const screenNode =
|
|
239
|
-
ScreenComponent && currentScreen ? (
|
|
240
|
-
<ScreenErrorBoundary screenName={currentScreen}>
|
|
241
|
-
<ScreenComponent {...screenPropsValue} />
|
|
242
|
-
</ScreenErrorBoundary>
|
|
243
|
-
) : null;
|
|
244
|
-
|
|
245
|
-
return (
|
|
246
|
-
<>
|
|
247
|
-
<BottomSheet
|
|
248
|
-
ref={sheetRef}
|
|
249
|
-
enablePanDownToClose
|
|
250
|
-
enableHandlePanningGesture
|
|
251
|
-
backgroundComponent={renderBackground}
|
|
252
|
-
style={styles.container}
|
|
253
|
-
onDismiss={handleDismiss}
|
|
254
|
-
onDismissAttempt={handleDismissAttempt}
|
|
255
|
-
scrollable={sheetConfig.scrollable}
|
|
256
|
-
manualActivation={sheetConfig.manualActivation}
|
|
257
|
-
dynamicBackdrop={sheetConfig.dynamicBackdrop}
|
|
258
|
-
handleComponent={sheetConfig.handleComponent}
|
|
259
|
-
>
|
|
260
|
-
{!isDialogPresentation && screenNode}
|
|
261
|
-
</BottomSheet>
|
|
262
|
-
{/* Always-mounted responsive Dialog surface for `presentation:
|
|
263
|
-
'dialog'` routes (currently the flagship photo picker). It stays
|
|
264
|
-
inert (`open={false}`, no child) for the ~28 sheet routes, so they
|
|
265
|
-
keep byte-for-byte identical behavior. `contentPadding={0}` +
|
|
266
|
-
the full-bleed black, rounded, clipped surface let the picker
|
|
267
|
-
paint edge-to-edge; `dismissOnBackdrop={false}` keeps the
|
|
268
|
-
controlled open state authoritative (dismissal flows through the
|
|
269
|
-
store, matching OxyAccountDialog). */}
|
|
270
|
-
<Dialog
|
|
271
|
-
open={isOpen && isDialogPresentation}
|
|
272
|
-
onClose={handleDismiss}
|
|
273
|
-
placement={DIALOG_PLACEMENT}
|
|
274
|
-
dismissOnBackdrop={false}
|
|
275
|
-
contentPadding={0}
|
|
276
|
-
maxWidth={640}
|
|
277
|
-
maxHeightRatio={0.9}
|
|
278
|
-
style={styles.dialogSurface}
|
|
279
|
-
panelStyle={styles.dialogSurface}
|
|
280
|
-
label={currentScreen ?? undefined}
|
|
281
|
-
>
|
|
282
|
-
{isDialogPresentation ? screenNode : null}
|
|
283
|
-
</Dialog>
|
|
284
|
-
</>
|
|
285
|
-
);
|
|
286
|
-
};
|
|
287
|
-
|
|
288
|
-
const styles = StyleSheet.create({
|
|
289
|
-
container: {
|
|
290
|
-
maxWidth: 800,
|
|
291
|
-
width: '100%',
|
|
292
|
-
alignSelf: 'center',
|
|
293
|
-
marginHorizontal: 'auto',
|
|
294
|
-
},
|
|
295
|
-
background: {
|
|
296
|
-
borderTopLeftRadius: 20,
|
|
297
|
-
borderTopRightRadius: 20,
|
|
298
|
-
overflow: 'hidden',
|
|
299
|
-
},
|
|
300
|
-
// Full-bleed black surface for `presentation: 'dialog'` routes. `overflow:
|
|
301
|
-
// 'hidden'` clips the picker's edge-to-edge black content to the panel's
|
|
302
|
-
// rounded corners (Dialog supplies the radius per placement); the black
|
|
303
|
-
// fill covers any sub-pixel gap behind the picker during entrance.
|
|
304
|
-
dialogSurface: {
|
|
305
|
-
backgroundColor: '#000000',
|
|
306
|
-
overflow: 'hidden',
|
|
307
|
-
},
|
|
308
|
-
});
|
|
309
|
-
|
|
310
|
-
export default React.memo(BottomSheetRouter);
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { getSheetConfig } from '../routes';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* `getSheetConfig` drives which surface `BottomSheetRouter` mounts a route in.
|
|
5
|
-
* The flagship image picker (FileManagement in image-only select mode) resolves
|
|
6
|
-
* to `presentation: 'dialog'`; every other route stays `'sheet'`. These guard
|
|
7
|
-
* the routing contract so the ~28 sheet screens keep the in-tree BottomSheet.
|
|
8
|
-
*/
|
|
9
|
-
describe('getSheetConfig presentation', () => {
|
|
10
|
-
const imageOnlyPickerProps = {
|
|
11
|
-
selectMode: true,
|
|
12
|
-
disabledMimeTypes: ['video/', 'audio/', 'application/pdf'],
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
it('defaults every route to the in-tree sheet', () => {
|
|
16
|
-
expect(getSheetConfig('ManageAccount', {}).presentation).toBe('sheet');
|
|
17
|
-
expect(getSheetConfig('AvatarCrop', {}).presentation).toBe('sheet');
|
|
18
|
-
expect(getSheetConfig(null, {}).presentation).toBe('sheet');
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
it('routes the FileManagement image-only picker to the Dialog', () => {
|
|
22
|
-
expect(getSheetConfig('FileManagement', imageOnlyPickerProps).presentation).toBe('dialog');
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it('keeps FileManagement on the sheet when it is not an image-only picker', () => {
|
|
26
|
-
// Browse mode (no selectMode) — the standard file manager.
|
|
27
|
-
expect(getSheetConfig('FileManagement', {}).presentation).toBe('sheet');
|
|
28
|
-
// Select mode that still allows non-image types is not the flagship picker.
|
|
29
|
-
expect(
|
|
30
|
-
getSheetConfig('FileManagement', {
|
|
31
|
-
selectMode: true,
|
|
32
|
-
disabledMimeTypes: ['video/'],
|
|
33
|
-
}).presentation,
|
|
34
|
-
).toBe('sheet');
|
|
35
|
-
});
|
|
36
|
-
});
|