@lodev09/react-native-true-sheet 4.0.0-beta.3 → 4.0.0-beta.30
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 +28 -5
- package/android/build.gradle +23 -1
- package/android/proguard-rules.pro +3 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContainerView.kt +50 -16
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentView.kt +303 -184
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentViewManager.kt +5 -1
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetFooterView.kt +38 -109
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetModule.kt +13 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetOverlayView.kt +127 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetOverlayViewManager.kt +45 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetPackage.kt +2 -1
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetStateUpdater.kt +29 -3
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +234 -66
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewController.kt +491 -186
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt +64 -10
- package/android/src/main/java/com/lodev09/truesheet/core/RNScreensEventObserver.kt +31 -14
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetBottomSheetBehavior.kt +135 -0
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetBottomSheetView.kt +23 -23
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetCoordinatorLayout.kt +130 -6
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetDetentCalculator.kt +104 -39
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetDimView.kt +14 -17
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetGrabberView.kt +2 -4
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetOverlayRootView.kt +148 -0
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetStackManager.kt +33 -40
- package/android/src/main/java/com/lodev09/truesheet/events/TrueSheetLifecycleEvents.kt +15 -0
- package/android/src/main/java/com/lodev09/truesheet/utils/ColorUtils.kt +19 -0
- package/android/src/main/java/com/lodev09/truesheet/utils/KeyboardUtils.kt +15 -2
- package/android/src/main/java/com/lodev09/truesheet/utils/ScreenUtils.kt +0 -12
- package/android/src/main/java/com/lodev09/truesheet/utils/ViewUtils.kt +19 -7
- package/android/src/main/jni/TrueSheetSpec.h +1 -0
- package/android/src/main/jni/TrueSheetStateUpdater.cpp +37 -6
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewComponentDescriptor.h +1 -9
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.cpp +114 -30
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.h +30 -7
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewState.cpp +2 -2
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewState.h +9 -8
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewComponentDescriptor.h +3 -5
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.cpp +14 -3
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.h +5 -6
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewState.cpp +1 -1
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewState.h +10 -6
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetInsets.cpp +1 -1
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetInsets.h +1 -1
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetLayoutUtils.h +43 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewComponentDescriptor.h +21 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewShadowNode.cpp +17 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewShadowNode.h +33 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewComponentDescriptor.h +3 -5
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewShadowNode.cpp +7 -40
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewShadowNode.h +3 -7
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewState.cpp +3 -5
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewState.h +4 -5
- package/ios/TrueSheetContainerView.h +23 -7
- package/ios/TrueSheetContainerView.mm +45 -25
- package/ios/TrueSheetContentView.h +44 -15
- package/ios/TrueSheetContentView.mm +221 -190
- package/ios/TrueSheetFooterView.mm +133 -28
- package/ios/TrueSheetModule.h +2 -7
- package/ios/TrueSheetModule.mm +18 -18
- package/ios/TrueSheetOverlayView.h +42 -0
- package/ios/TrueSheetOverlayView.mm +175 -0
- package/ios/TrueSheetView.h +2 -0
- package/ios/TrueSheetView.mm +268 -52
- package/ios/TrueSheetViewController.h +36 -3
- package/ios/TrueSheetViewController.mm +797 -102
- package/ios/core/RNScreensEventObserver.mm +31 -28
- package/ios/core/TrueSheetBlurView.h +0 -2
- package/ios/core/TrueSheetBlurView.mm +3 -36
- package/ios/core/TrueSheetDetentCalculator.h +18 -1
- package/ios/core/TrueSheetDetentCalculator.mm +44 -9
- package/ios/core/TrueSheetDimView.h +27 -0
- package/ios/core/TrueSheetDimView.mm +41 -0
- package/ios/core/TrueSheetGrabberView.mm +13 -3
- package/ios/core/TrueSheetKeyboardObserver.h +7 -0
- package/ios/core/TrueSheetKeyboardObserver.mm +107 -15
- package/ios/core/TrueSheetOverlayContainerView.h +31 -0
- package/ios/core/TrueSheetOverlayContainerView.mm +35 -0
- package/ios/events/TrueSheetLifecycleEvents.h +2 -0
- package/ios/events/TrueSheetLifecycleEvents.mm +8 -0
- package/ios/tvos/TrueSheetStubs.mm +12 -0
- package/ios/utils/UIView+ScrollEdgeInteraction.h +1 -0
- package/ios/utils/UIView+ScrollEdgeInteraction.mm +24 -2
- package/lib/module/TrueSheet.js +222 -54
- package/lib/module/TrueSheet.js.map +1 -1
- package/lib/module/TrueSheet.web.js +364 -275
- package/lib/module/TrueSheet.web.js.map +1 -1
- package/lib/module/TrueSheetBackground.js +15 -0
- package/lib/module/TrueSheetBackground.js.map +1 -0
- package/lib/module/TrueSheetOverlay.js +30 -0
- package/lib/module/TrueSheetOverlay.js.map +1 -0
- package/lib/module/TrueSheetOverlay.web.js +35 -0
- package/lib/module/TrueSheetOverlay.web.js.map +1 -0
- package/lib/module/TrueSheetPeek.web.js +20 -15
- package/lib/module/TrueSheetPeek.web.js.map +1 -1
- package/lib/module/TrueSheetProvider.web.js +13 -9
- package/lib/module/TrueSheetProvider.web.js.map +1 -1
- package/lib/module/detentBackgrounds.js +21 -0
- package/lib/module/detentBackgrounds.js.map +1 -0
- package/lib/module/fabric/TrueSheetContentViewNativeComponent.ts +1 -1
- package/lib/module/fabric/TrueSheetFooterViewNativeComponent.ts +2 -3
- package/lib/module/fabric/TrueSheetOverlayViewNativeComponent.ts +12 -0
- package/lib/module/fabric/TrueSheetViewNativeComponent.ts +89 -73
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/mocks/index.js +18 -2
- package/lib/module/mocks/index.js.map +1 -1
- package/lib/module/mocks/navigationExpoRouter.js.map +1 -1
- package/lib/module/navigation/base-types.js +2 -0
- package/lib/module/navigation/base-types.js.map +1 -0
- package/lib/module/navigation/createTrueSheetRouter.js +158 -100
- package/lib/module/navigation/createTrueSheetRouter.js.map +1 -1
- package/lib/module/navigation/expo-router/base-types.js +2 -0
- package/lib/module/navigation/expo-router/base-types.js.map +1 -0
- package/lib/module/navigation/expo-router/extendTrueSheetRouter.js +71 -0
- package/lib/module/navigation/expo-router/extendTrueSheetRouter.js.map +1 -0
- package/lib/module/navigation/expo-router/index.js +18 -7
- package/lib/module/navigation/expo-router/index.js.map +1 -1
- package/lib/module/navigation/expo-router/types.js +4 -0
- package/lib/module/navigation/expo-router/types.js.map +1 -0
- package/lib/module/navigation/index.js.map +1 -1
- package/lib/module/navigation/screen/useSheetScreenState.js +1 -0
- package/lib/module/navigation/screen/useSheetScreenState.js.map +1 -1
- package/lib/module/scrollable.js +28 -0
- package/lib/module/scrollable.js.map +1 -0
- package/lib/module/web/constants.js +1 -1
- package/lib/module/web/constants.js.map +1 -1
- package/lib/module/web/keyboard.js +69 -0
- package/lib/module/web/keyboard.js.map +1 -0
- package/lib/module/web/layout.js +168 -0
- package/lib/module/web/layout.js.map +1 -0
- package/lib/module/web/vaul/constants.js +9 -0
- package/lib/module/web/vaul/constants.js.map +1 -1
- package/lib/module/web/vaul/context.js +4 -0
- package/lib/module/web/vaul/context.js.map +1 -1
- package/lib/module/web/vaul/helpers.js +1 -0
- package/lib/module/web/vaul/helpers.js.map +1 -1
- package/lib/module/web/vaul/index.js +83 -21
- package/lib/module/web/vaul/index.js.map +1 -1
- package/lib/module/web/vaul/use-snap-points.js +57 -28
- package/lib/module/web/vaul/use-snap-points.js.map +1 -1
- package/lib/typescript/src/TrueSheet.d.ts +18 -1
- package/lib/typescript/src/TrueSheet.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheet.types.d.ts +209 -35
- package/lib/typescript/src/TrueSheet.types.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheet.web.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheetBackground.d.ts +3 -0
- package/lib/typescript/src/TrueSheetBackground.d.ts.map +1 -0
- package/lib/typescript/src/TrueSheetOverlay.d.ts +8 -0
- package/lib/typescript/src/TrueSheetOverlay.d.ts.map +1 -0
- package/lib/typescript/src/TrueSheetOverlay.web.d.ts +8 -0
- package/lib/typescript/src/TrueSheetOverlay.web.d.ts.map +1 -0
- package/lib/typescript/src/TrueSheetPeek.web.d.ts +8 -4
- package/lib/typescript/src/TrueSheetPeek.web.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheetProvider.web.d.ts +5 -1
- package/lib/typescript/src/TrueSheetProvider.web.d.ts.map +1 -1
- package/lib/typescript/src/detentBackgrounds.d.ts +10 -0
- package/lib/typescript/src/detentBackgrounds.d.ts.map +1 -0
- package/lib/typescript/src/fabric/TrueSheetFooterViewNativeComponent.d.ts +2 -3
- package/lib/typescript/src/fabric/TrueSheetFooterViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/fabric/TrueSheetOverlayViewNativeComponent.d.ts +6 -0
- package/lib/typescript/src/fabric/TrueSheetOverlayViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts +76 -65
- package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/mocks/index.d.ts +4 -0
- package/lib/typescript/src/mocks/index.d.ts.map +1 -1
- package/lib/typescript/src/mocks/navigationExpoRouter.d.ts +3 -3
- package/lib/typescript/src/mocks/navigationExpoRouter.d.ts.map +1 -1
- package/lib/typescript/src/navigation/base-types.d.ts +9 -0
- package/lib/typescript/src/navigation/base-types.d.ts.map +1 -0
- package/lib/typescript/src/navigation/createTrueSheetRouter.d.ts +36 -10
- package/lib/typescript/src/navigation/createTrueSheetRouter.d.ts.map +1 -1
- package/lib/typescript/src/navigation/expo-router/base-types.d.ts +8 -0
- package/lib/typescript/src/navigation/expo-router/base-types.d.ts.map +1 -0
- package/lib/typescript/src/navigation/expo-router/extendTrueSheetRouter.d.ts +33 -0
- package/lib/typescript/src/navigation/expo-router/extendTrueSheetRouter.d.ts.map +1 -0
- package/lib/typescript/src/navigation/expo-router/index.d.ts +9 -6
- package/lib/typescript/src/navigation/expo-router/index.d.ts.map +1 -1
- package/lib/typescript/src/navigation/expo-router/types.d.ts +44 -0
- package/lib/typescript/src/navigation/expo-router/types.d.ts.map +1 -0
- package/lib/typescript/src/navigation/index.d.ts +3 -4
- package/lib/typescript/src/navigation/index.d.ts.map +1 -1
- package/lib/typescript/src/navigation/screen/useSheetScreenState.d.ts +2 -1
- package/lib/typescript/src/navigation/screen/useSheetScreenState.d.ts.map +1 -1
- package/lib/typescript/src/navigation/types.d.ts +43 -6
- package/lib/typescript/src/navigation/types.d.ts.map +1 -1
- package/lib/typescript/src/scrollable.d.ts +2 -0
- package/lib/typescript/src/scrollable.d.ts.map +1 -0
- package/lib/typescript/src/web/constants.d.ts +1 -1
- package/lib/typescript/src/web/constants.d.ts.map +1 -1
- package/lib/typescript/src/web/keyboard.d.ts +15 -0
- package/lib/typescript/src/web/keyboard.d.ts.map +1 -0
- package/lib/typescript/src/web/layout.d.ts +20 -0
- package/lib/typescript/src/web/layout.d.ts.map +1 -0
- package/lib/typescript/src/web/vaul/constants.d.ts +3 -0
- package/lib/typescript/src/web/vaul/constants.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/context.d.ts +5 -1
- package/lib/typescript/src/web/vaul/context.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/helpers.d.ts +1 -0
- package/lib/typescript/src/web/vaul/helpers.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/index.d.ts +20 -1
- package/lib/typescript/src/web/vaul/index.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/types.d.ts +9 -0
- package/lib/typescript/src/web/vaul/types.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/use-snap-points.d.ts +6 -4
- package/lib/typescript/src/web/vaul/use-snap-points.d.ts.map +1 -1
- package/package.json +18 -8
- package/react-native.config.js +1 -0
- package/src/TrueSheet.tsx +257 -62
- package/src/TrueSheet.types.ts +225 -35
- package/src/TrueSheet.web.tsx +445 -333
- package/src/TrueSheetBackground.tsx +17 -0
- package/src/TrueSheetOverlay.tsx +24 -0
- package/src/TrueSheetOverlay.web.tsx +33 -0
- package/src/TrueSheetPeek.web.tsx +25 -23
- package/src/TrueSheetProvider.web.tsx +22 -13
- package/src/detentBackgrounds.ts +24 -0
- package/src/fabric/TrueSheetContentViewNativeComponent.ts +1 -1
- package/src/fabric/TrueSheetFooterViewNativeComponent.ts +2 -3
- package/src/fabric/TrueSheetOverlayViewNativeComponent.ts +12 -0
- package/src/fabric/TrueSheetViewNativeComponent.ts +89 -73
- package/src/index.ts +1 -0
- package/src/mocks/index.ts +17 -2
- package/src/mocks/navigationExpoRouter.ts +6 -5
- package/src/navigation/base-types.ts +20 -0
- package/src/navigation/createTrueSheetRouter.ts +220 -144
- package/src/navigation/expo-router/base-types.ts +18 -0
- package/src/navigation/expo-router/extendTrueSheetRouter.ts +99 -0
- package/src/navigation/expo-router/index.ts +41 -30
- package/src/navigation/expo-router/types.ts +116 -0
- package/src/navigation/index.ts +6 -7
- package/src/navigation/screen/useSheetScreenState.ts +2 -0
- package/src/navigation/types.ts +81 -23
- package/src/scrollable.ts +25 -0
- package/src/web/constants.ts +1 -1
- package/src/web/keyboard.ts +79 -0
- package/src/web/layout.ts +196 -0
- package/src/web/vaul/constants.ts +9 -0
- package/src/web/vaul/context.ts +7 -1
- package/src/web/vaul/helpers.ts +5 -0
- package/src/web/vaul/index.tsx +113 -16
- package/src/web/vaul/types.ts +10 -0
- package/src/web/vaul/use-snap-points.ts +86 -33
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { StyleSheet, View } from 'react-native';
|
|
2
|
+
import type { TrueSheetProps } from './TrueSheet.types';
|
|
3
|
+
|
|
4
|
+
export const TrueSheetBackground = ({
|
|
5
|
+
background,
|
|
6
|
+
backgroundStyle,
|
|
7
|
+
}: Pick<TrueSheetProps, 'background' | 'backgroundStyle'>) => (
|
|
8
|
+
<View
|
|
9
|
+
pointerEvents="none"
|
|
10
|
+
style={[
|
|
11
|
+
StyleSheet.absoluteFill,
|
|
12
|
+
{ backgroundColor: StyleSheet.flatten(backgroundStyle)?.backgroundColor },
|
|
13
|
+
]}
|
|
14
|
+
>
|
|
15
|
+
{background}
|
|
16
|
+
</View>
|
|
17
|
+
);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { StyleSheet, type ViewProps } from 'react-native';
|
|
2
|
+
|
|
3
|
+
import TrueSheetOverlayViewNativeComponent from './fabric/TrueSheetOverlayViewNativeComponent';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Renders its children in a native layer above every presented sheet — for
|
|
7
|
+
* toasts, dialogs, and other content a sheet must not cover.
|
|
8
|
+
* Fills the window; touches that miss its children pass through to the views beneath.
|
|
9
|
+
*/
|
|
10
|
+
export const TrueSheetOverlay = ({ style, ...rest }: ViewProps) => (
|
|
11
|
+
<TrueSheetOverlayViewNativeComponent {...rest} style={[styles.overlay, style]} />
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
const styles = StyleSheet.create({
|
|
15
|
+
// Sized to the window from native — absolute so it takes no layout space.
|
|
16
|
+
// Children render in a native container, so the host itself must never
|
|
17
|
+
// catch touches (Android forces it visible on layout).
|
|
18
|
+
overlay: {
|
|
19
|
+
position: 'absolute',
|
|
20
|
+
top: 0,
|
|
21
|
+
left: 0,
|
|
22
|
+
pointerEvents: 'none',
|
|
23
|
+
},
|
|
24
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/// <reference lib="dom" />
|
|
2
|
+
import { useLayoutEffect, useState } from 'react';
|
|
3
|
+
import { createPortal } from 'react-dom';
|
|
4
|
+
import { StyleSheet, View, type ViewProps } from 'react-native';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Renders its children in a layer above every presented sheet — for
|
|
8
|
+
* toasts, dialogs, and other content a sheet must not cover.
|
|
9
|
+
* Fills the window; touches that miss its children pass through to the views beneath.
|
|
10
|
+
*/
|
|
11
|
+
export const TrueSheetOverlay = ({ style, ...rest }: ViewProps) => {
|
|
12
|
+
// Portal target appended to the body so it stacks above the sheets' portal
|
|
13
|
+
const [container] = useState(() =>
|
|
14
|
+
typeof document !== 'undefined' ? document.createElement('div') : null
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
useLayoutEffect(() => {
|
|
18
|
+
if (!container) return;
|
|
19
|
+
|
|
20
|
+
container.style.cssText = 'position:fixed;inset:0;pointer-events:none';
|
|
21
|
+
document.body.appendChild(container);
|
|
22
|
+
return () => {
|
|
23
|
+
container.remove();
|
|
24
|
+
};
|
|
25
|
+
}, [container]);
|
|
26
|
+
|
|
27
|
+
if (!container) return null;
|
|
28
|
+
|
|
29
|
+
return createPortal(
|
|
30
|
+
<View pointerEvents="box-none" {...rest} style={[StyleSheet.absoluteFill, style]} />,
|
|
31
|
+
container
|
|
32
|
+
);
|
|
33
|
+
};
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import { createContext, type RefObject, useContext,
|
|
1
|
+
import { createContext, type RefObject, useContext, useLayoutEffect, useRef } from 'react';
|
|
2
2
|
import { type LayoutChangeEvent, View, type ViewProps } from 'react-native';
|
|
3
3
|
|
|
4
|
-
import { getDOMElement } from './web/dom';
|
|
5
|
-
|
|
6
4
|
/**
|
|
7
|
-
*
|
|
5
|
+
* Registers a peek with the owning TrueSheet so it can measure the peek live.
|
|
8
6
|
* @internal
|
|
9
7
|
*/
|
|
10
8
|
export interface TrueSheetPeekContextValue {
|
|
11
9
|
contentRef: RefObject<View | null>;
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
attachPeek: (view: View) => void;
|
|
11
|
+
detachPeek: (view: View) => void;
|
|
12
|
+
measurePeek: (view: View) => void;
|
|
14
13
|
}
|
|
15
14
|
|
|
16
15
|
export const TrueSheetPeekContext = createContext<TrueSheetPeekContextValue | null>(null);
|
|
@@ -19,14 +18,19 @@ export const TrueSheetPeekContext = createContext<TrueSheetPeekContextValue | nu
|
|
|
19
18
|
* Distance from the top of the content view to the bottom of the peek view,
|
|
20
19
|
* so the peek view's offset within the content (padding, views above it)
|
|
21
20
|
* counts toward the peek detent. Both rects live in the drawer's transformed
|
|
22
|
-
* subtree, so an in-flight translate cancels out of the delta.
|
|
21
|
+
* subtree, so an in-flight translate cancels out of the delta. Rounded so the
|
|
22
|
+
* sub-pixel noise of a mid-transition measurement doesn't register as a
|
|
23
|
+
* change — the content re-measures every frame while the snap animates, and
|
|
24
|
+
* a new value would restart the snap.
|
|
23
25
|
* @internal
|
|
24
26
|
*/
|
|
25
27
|
export const measurePeekContentHeight = (
|
|
26
28
|
peekElement: HTMLElement,
|
|
27
29
|
contentElement: HTMLElement
|
|
28
30
|
): number =>
|
|
29
|
-
|
|
31
|
+
Math.round(
|
|
32
|
+
peekElement.getBoundingClientRect().bottom - contentElement.getBoundingClientRect().top
|
|
33
|
+
);
|
|
30
34
|
|
|
31
35
|
/**
|
|
32
36
|
* Wrapper component that marks its children as the sheet's peek content.
|
|
@@ -36,25 +40,23 @@ export const measurePeekContentHeight = (
|
|
|
36
40
|
*/
|
|
37
41
|
export const TrueSheetPeek = ({ onLayout, ...rest }: ViewProps) => {
|
|
38
42
|
const context = useContext(TrueSheetPeekContext);
|
|
39
|
-
const
|
|
43
|
+
const viewRef = useRef<View>(null);
|
|
40
44
|
|
|
41
|
-
//
|
|
42
|
-
//
|
|
43
|
-
|
|
45
|
+
// Attach by instance rather than sharing a ref — during a screen swap the
|
|
46
|
+
// incoming peek mounts before the outgoing one unmounts, and a shared ref
|
|
47
|
+
// would be nulled by the outgoing unmount.
|
|
48
|
+
useLayoutEffect(() => {
|
|
49
|
+
const view = viewRef.current;
|
|
50
|
+
if (!context || !view) return;
|
|
44
51
|
|
|
45
|
-
|
|
52
|
+
context.attachPeek(view);
|
|
53
|
+
return () => context.detachPeek(view);
|
|
54
|
+
}, [context]);
|
|
46
55
|
|
|
47
56
|
const handleLayout = (event: LayoutChangeEvent) => {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const bottom =
|
|
53
|
-
peekElement && contentElement
|
|
54
|
-
? measurePeekContentHeight(peekElement, contentElement)
|
|
55
|
-
: event.nativeEvent.layout.height;
|
|
56
|
-
|
|
57
|
-
context.setPeekContentHeight(bottom);
|
|
57
|
+
const view = viewRef.current;
|
|
58
|
+
if (context && view) {
|
|
59
|
+
context.measurePeek(view);
|
|
58
60
|
}
|
|
59
61
|
|
|
60
62
|
onLayout?.(event);
|
|
@@ -13,7 +13,13 @@ import {
|
|
|
13
13
|
|
|
14
14
|
import type { TrueSheetMethods, TrueSheetStaticMethods } from './TrueSheet.types';
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
export interface SheetHandle {
|
|
17
|
+
methods: TrueSheetMethods;
|
|
18
|
+
// dismiss() without the already-dismissed warning, for stack-wide dismissals
|
|
19
|
+
dismissQuietly: (animated?: boolean) => Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
type SheetRef = RefObject<SheetHandle | null>;
|
|
17
23
|
type NodeRef = RefObject<HTMLDivElement | null>;
|
|
18
24
|
|
|
19
25
|
interface StackEntry {
|
|
@@ -23,7 +29,8 @@ interface StackEntry {
|
|
|
23
29
|
}
|
|
24
30
|
|
|
25
31
|
interface SheetContextValue {
|
|
26
|
-
|
|
32
|
+
registerSheet: (ref: SheetRef, name?: string) => () => void;
|
|
33
|
+
getSheets: () => ReadonlySet<SheetRef>;
|
|
27
34
|
resolveByName: (name: string) => TrueSheetMethods;
|
|
28
35
|
pushOpen: (entry: StackEntry) => void;
|
|
29
36
|
popOpen: (entry: StackEntry) => void;
|
|
@@ -44,6 +51,7 @@ export interface TrueSheetProviderProps {
|
|
|
44
51
|
}
|
|
45
52
|
|
|
46
53
|
export function TrueSheetProvider({ children }: TrueSheetProviderProps) {
|
|
54
|
+
const sheetsRef = useRef<Set<SheetRef>>(new Set());
|
|
47
55
|
const namedSheetsRef = useRef<Map<string, SheetRef>>(new Map());
|
|
48
56
|
const stackRef = useRef<readonly StackEntry[]>(EMPTY_STACK);
|
|
49
57
|
const listenersRef = useRef<Set<() => void>>(new Set());
|
|
@@ -72,17 +80,20 @@ export function TrueSheetProvider({ children }: TrueSheetProviderProps) {
|
|
|
72
80
|
const notify = () => listenersRef.current.forEach((listener) => listener());
|
|
73
81
|
|
|
74
82
|
return {
|
|
75
|
-
|
|
76
|
-
|
|
83
|
+
registerSheet: (ref, name) => {
|
|
84
|
+
sheetsRef.current.add(ref);
|
|
85
|
+
if (name) namedSheetsRef.current.set(name, ref);
|
|
77
86
|
return () => {
|
|
78
|
-
|
|
87
|
+
sheetsRef.current.delete(ref);
|
|
88
|
+
if (name && namedSheetsRef.current.get(name) === ref) {
|
|
79
89
|
namedSheetsRef.current.delete(name);
|
|
80
90
|
}
|
|
81
91
|
};
|
|
82
92
|
},
|
|
93
|
+
getSheets: () => sheetsRef.current,
|
|
83
94
|
resolveByName: (name) => {
|
|
84
95
|
const ref = namedSheetsRef.current.get(name);
|
|
85
|
-
const methods = ref?.current;
|
|
96
|
+
const methods = ref?.current?.methods;
|
|
86
97
|
if (!methods) {
|
|
87
98
|
throw new Error(`TrueSheet: no sheet registered with name "${name}"`);
|
|
88
99
|
}
|
|
@@ -145,11 +156,9 @@ export function useTrueSheet(): TrueSheetStaticMethods {
|
|
|
145
156
|
resize: (name, index) => ctx.resolveByName(name).resize(index),
|
|
146
157
|
dismiss: (name, animated) => ctx.resolveByName(name).dismiss(animated),
|
|
147
158
|
dismissStack: (name, animated) => ctx.resolveByName(name).dismissStack(animated),
|
|
159
|
+
// Every sheet, not just the open stack — it misses a present() that hasn't committed yet
|
|
148
160
|
dismissAll: async (animated) => {
|
|
149
|
-
|
|
150
|
-
await Promise.all(
|
|
151
|
-
[...stack].reverse().map((entry) => entry.ref.current?.dismiss(animated))
|
|
152
|
-
);
|
|
161
|
+
await Promise.all([...ctx.getSheets()].map((ref) => ref.current?.dismissQuietly(animated)));
|
|
153
162
|
},
|
|
154
163
|
};
|
|
155
164
|
}, [ctx]);
|
|
@@ -158,8 +167,8 @@ export function useTrueSheet(): TrueSheetStaticMethods {
|
|
|
158
167
|
export function useRegisterSheet(name: string | undefined, ref: SheetRef): void {
|
|
159
168
|
const ctx = useContext(SheetContext);
|
|
160
169
|
useEffect(() => {
|
|
161
|
-
if (!ctx
|
|
162
|
-
return ctx.
|
|
170
|
+
if (!ctx) return;
|
|
171
|
+
return ctx.registerSheet(ref, name);
|
|
163
172
|
}, [ctx, name, ref]);
|
|
164
173
|
}
|
|
165
174
|
|
|
@@ -211,7 +220,7 @@ export function useSheetStack(
|
|
|
211
220
|
const idx = snapshot.findIndex((e) => e.ref === ref);
|
|
212
221
|
if (idx < 0) return;
|
|
213
222
|
const above = snapshot.slice(idx + 1);
|
|
214
|
-
await Promise.all([...above].reverse().map((e) => e.ref.current?.
|
|
223
|
+
await Promise.all([...above].reverse().map((e) => e.ref.current?.dismissQuietly(animated)));
|
|
215
224
|
},
|
|
216
225
|
[ctx, ref]
|
|
217
226
|
);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { DetentBackground } from './TrueSheet.types';
|
|
2
|
+
|
|
3
|
+
export function normalizeDetentBackground(entry: DetentBackground | null | undefined) {
|
|
4
|
+
return typeof entry === 'string' ? { color: entry } : entry;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function getDetentBackgroundIndex(
|
|
8
|
+
height: number,
|
|
9
|
+
detentHeights: readonly number[],
|
|
10
|
+
displayedIndex: number
|
|
11
|
+
): number {
|
|
12
|
+
if (detentHeights.length === 0) return -1;
|
|
13
|
+
|
|
14
|
+
let nextIndex = Math.max(0, Math.min(displayedIndex, detentHeights.length - 1));
|
|
15
|
+
let distance = Math.abs(height - detentHeights[nextIndex]!);
|
|
16
|
+
for (let index = 0; index < detentHeights.length; index++) {
|
|
17
|
+
const nextDistance = Math.abs(height - detentHeights[index]!);
|
|
18
|
+
if (nextDistance < distance) {
|
|
19
|
+
nextIndex = index;
|
|
20
|
+
distance = nextDistance;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return nextIndex;
|
|
24
|
+
}
|
|
@@ -6,7 +6,7 @@ export interface NativeProps extends ViewProps {
|
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
// interfaceOnly: shadow node/state/descriptor are custom (common/cpp) so the
|
|
9
|
-
// content can be bounded to the container when a ScrollView is
|
|
9
|
+
// content can be bounded to the container when a ScrollView is detected
|
|
10
10
|
export default codegenNativeComponent<NativeProps>('TrueSheetContentView', {
|
|
11
11
|
interfaceOnly: true,
|
|
12
12
|
});
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import type { ViewProps } from 'react-native';
|
|
2
|
-
import type { WithDefault } from 'react-native/Libraries/Types/CodegenTypes';
|
|
1
|
+
import type { CodegenTypes, ViewProps } from 'react-native';
|
|
3
2
|
import { codegenNativeComponent } from 'react-native';
|
|
4
3
|
|
|
5
4
|
export interface NativeProps extends ViewProps {
|
|
6
5
|
// Seeds the footer's first layout with the sheet's bottom safe-area inset
|
|
7
6
|
// (insetAdjustment: 'automatic') so a late-set footer doesn't need a second
|
|
8
7
|
// layout pass — and a visible sheet resize — once native pushes the inset
|
|
9
|
-
autoBottomInset?: WithDefault<boolean, false>;
|
|
8
|
+
autoBottomInset?: CodegenTypes.WithDefault<boolean, false>;
|
|
10
9
|
}
|
|
11
10
|
|
|
12
11
|
// interfaceOnly: shadow node/state/descriptor are custom (common/cpp) so the
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ViewProps } from 'react-native';
|
|
2
|
+
import { codegenNativeComponent } from 'react-native';
|
|
3
|
+
|
|
4
|
+
export interface NativeProps extends ViewProps {
|
|
5
|
+
// No props needed - sized to the window from native
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// interfaceOnly: shadow node/state/descriptor are custom (common/cpp) so the
|
|
9
|
+
// overlay is sized to the window
|
|
10
|
+
export default codegenNativeComponent<NativeProps>('TrueSheetOverlayView', {
|
|
11
|
+
interfaceOnly: true,
|
|
12
|
+
});
|
|
@@ -1,87 +1,98 @@
|
|
|
1
|
-
import type { ColorValue, ProcessedColorValue, ViewProps } from 'react-native';
|
|
2
|
-
import type {
|
|
3
|
-
DirectEventHandler,
|
|
4
|
-
Double,
|
|
5
|
-
Int32,
|
|
6
|
-
WithDefault,
|
|
7
|
-
} from 'react-native/Libraries/Types/CodegenTypes';
|
|
1
|
+
import type { CodegenTypes, ColorValue, ProcessedColorValue, ViewProps } from 'react-native';
|
|
8
2
|
import { codegenNativeComponent } from 'react-native';
|
|
9
3
|
|
|
10
4
|
type GrabberOptionsType = Readonly<{
|
|
11
|
-
width?: Double;
|
|
12
|
-
height?: Double;
|
|
13
|
-
topMargin?: Double;
|
|
14
|
-
cornerRadius?: WithDefault<Double, -1>;
|
|
5
|
+
width?: CodegenTypes.Double;
|
|
6
|
+
height?: CodegenTypes.Double;
|
|
7
|
+
topMargin?: CodegenTypes.Double;
|
|
8
|
+
cornerRadius?: CodegenTypes.WithDefault<CodegenTypes.Double, -1>;
|
|
15
9
|
color?: ProcessedColorValue | null;
|
|
16
|
-
adaptive?: WithDefault<boolean, true>;
|
|
10
|
+
adaptive?: CodegenTypes.WithDefault<boolean, true>;
|
|
17
11
|
}>;
|
|
18
12
|
|
|
19
13
|
type AccessibilityOptionsType = Readonly<{
|
|
20
|
-
grabberLabel?: WithDefault<string, 'Sheet Grabber'>;
|
|
21
|
-
grabberHint?: WithDefault<
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
intensity?: WithDefault<Double, -1>;
|
|
32
|
-
interaction?: WithDefault<boolean, true>;
|
|
14
|
+
grabberLabel?: CodegenTypes.WithDefault<string, 'Sheet Grabber'>;
|
|
15
|
+
grabberHint?: CodegenTypes.WithDefault<
|
|
16
|
+
string,
|
|
17
|
+
'Double-tap to expand. Swipe up or down to resize the sheet'
|
|
18
|
+
>;
|
|
19
|
+
expandedValue?: CodegenTypes.WithDefault<string, 'Expanded'>;
|
|
20
|
+
collapsedValue?: CodegenTypes.WithDefault<string, 'Collapsed'>;
|
|
21
|
+
detentValue?: CodegenTypes.WithDefault<string, 'Detent {index} of {count}'>;
|
|
22
|
+
expandActionLabel?: CodegenTypes.WithDefault<string, 'Expand'>;
|
|
23
|
+
collapseActionLabel?: CodegenTypes.WithDefault<string, 'Collapse'>;
|
|
24
|
+
paneTitle?: CodegenTypes.WithDefault<string, 'Bottom sheet'>;
|
|
33
25
|
}>;
|
|
34
26
|
|
|
35
27
|
type ScrollEdgeEffect = 'automatic' | 'hard' | 'soft' | 'hidden';
|
|
36
28
|
|
|
37
29
|
type ScrollableOptionsType = Readonly<{
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
30
|
+
contentInsetAdjustment?: CodegenTypes.WithDefault<
|
|
31
|
+
'automatic' | 'safe-area' | 'footer' | 'never',
|
|
32
|
+
'automatic'
|
|
33
|
+
>;
|
|
34
|
+
keyboardScrollOffset?: CodegenTypes.WithDefault<CodegenTypes.Double, 0>;
|
|
35
|
+
keyboardOffset?: CodegenTypes.WithDefault<CodegenTypes.Double, 0>;
|
|
36
|
+
scrollingExpandsSheet?: CodegenTypes.WithDefault<boolean, true>;
|
|
37
|
+
topScrollEdgeEffect?: CodegenTypes.WithDefault<ScrollEdgeEffect, 'hidden'>;
|
|
38
|
+
bottomScrollEdgeEffect?: CodegenTypes.WithDefault<ScrollEdgeEffect, 'hidden'>;
|
|
42
39
|
}>;
|
|
43
40
|
|
|
44
41
|
type FooterOptionsType = Readonly<{
|
|
45
42
|
// Named uniquely across option structs — codegen derives the enum name from
|
|
46
43
|
// the field name, so a second `position` would redefine TrueSheetViewPosition
|
|
47
|
-
footerPosition?: WithDefault<'relative' | 'absolute', 'relative'>;
|
|
48
|
-
keyboardOffset?: WithDefault<Double, 0>;
|
|
44
|
+
footerPosition?: CodegenTypes.WithDefault<'relative' | 'absolute', 'relative'>;
|
|
45
|
+
keyboardOffset?: CodegenTypes.WithDefault<CodegenTypes.Double, 0>;
|
|
46
|
+
avoidKeyboard?: CodegenTypes.WithDefault<boolean, true>;
|
|
49
47
|
}>;
|
|
50
48
|
|
|
51
49
|
type HeaderOptionsType = Readonly<{
|
|
52
|
-
position?: WithDefault<'relative' | 'absolute', 'relative'>;
|
|
50
|
+
position?: CodegenTypes.WithDefault<'relative' | 'absolute', 'relative'>;
|
|
51
|
+
}>;
|
|
52
|
+
|
|
53
|
+
type FoldOptionsType = Readonly<{
|
|
54
|
+
hingeDetentIndex?: CodegenTypes.WithDefault<CodegenTypes.Int32, -1>;
|
|
55
|
+
hingeBehavior?: CodegenTypes.WithDefault<'none' | 'avoid' | 'snap', 'none'>;
|
|
53
56
|
}>;
|
|
54
57
|
|
|
55
58
|
export interface DetentInfoEventPayload {
|
|
56
|
-
index: Int32;
|
|
57
|
-
position: Double;
|
|
58
|
-
detent: Double;
|
|
59
|
+
index: CodegenTypes.Int32;
|
|
60
|
+
position: CodegenTypes.Double;
|
|
61
|
+
detent: CodegenTypes.Double;
|
|
59
62
|
}
|
|
60
63
|
|
|
61
64
|
export interface PositionChangeEventPayload {
|
|
62
|
-
index: Double;
|
|
63
|
-
position: Double;
|
|
64
|
-
detent: Double;
|
|
65
|
+
index: CodegenTypes.Double;
|
|
66
|
+
position: CodegenTypes.Double;
|
|
67
|
+
detent: CodegenTypes.Double;
|
|
65
68
|
realtime: boolean;
|
|
66
69
|
}
|
|
67
70
|
|
|
68
71
|
export interface NativeProps extends ViewProps {
|
|
69
72
|
// Array properties
|
|
70
|
-
detents?: ReadonlyArray<Double>;
|
|
73
|
+
detents?: ReadonlyArray<CodegenTypes.Double>;
|
|
74
|
+
detentBackgrounds?: ReadonlyArray<
|
|
75
|
+
Readonly<{
|
|
76
|
+
color?: ProcessedColorValue | null;
|
|
77
|
+
blur?: string;
|
|
78
|
+
}>
|
|
79
|
+
>;
|
|
71
80
|
|
|
72
81
|
// Number properties - use 0 as default to avoid nil insertion
|
|
73
|
-
maxContentHeight?: WithDefault<Double, 0>;
|
|
74
|
-
maxContentWidth?: WithDefault<Double, 0>;
|
|
75
|
-
cornerRadius?: WithDefault<Double, -1>;
|
|
76
|
-
elevation?: WithDefault<Double, -1>;
|
|
82
|
+
maxContentHeight?: CodegenTypes.WithDefault<CodegenTypes.Double, 0>;
|
|
83
|
+
maxContentWidth?: CodegenTypes.WithDefault<CodegenTypes.Double, 0>;
|
|
84
|
+
cornerRadius?: CodegenTypes.WithDefault<CodegenTypes.Double, -1>;
|
|
85
|
+
elevation?: CodegenTypes.WithDefault<CodegenTypes.Double, -1>;
|
|
77
86
|
|
|
78
87
|
// Color properties
|
|
79
88
|
backgroundColor?: ColorValue;
|
|
80
|
-
initialDetentIndex?: WithDefault<Int32, -1>;
|
|
81
|
-
|
|
89
|
+
initialDetentIndex?: CodegenTypes.WithDefault<CodegenTypes.Int32, -1>;
|
|
90
|
+
dimColor?: ColorValue;
|
|
91
|
+
dimOpacity?: CodegenTypes.WithDefault<CodegenTypes.Double, -1>;
|
|
92
|
+
dimmedDetentIndex?: CodegenTypes.WithDefault<CodegenTypes.Int32, 0>;
|
|
82
93
|
|
|
83
94
|
// String properties - use empty string as default to avoid nil insertion
|
|
84
|
-
backgroundBlur?: WithDefault<
|
|
95
|
+
backgroundBlur?: CodegenTypes.WithDefault<
|
|
85
96
|
| 'none'
|
|
86
97
|
| 'light'
|
|
87
98
|
| 'dark'
|
|
@@ -107,42 +118,47 @@ export interface NativeProps extends ViewProps {
|
|
|
107
118
|
'none'
|
|
108
119
|
>;
|
|
109
120
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
121
|
+
placement?: CodegenTypes.WithDefault<
|
|
122
|
+
'automatic' | 'leading' | 'center' | 'trailing',
|
|
123
|
+
'automatic'
|
|
124
|
+
>;
|
|
125
|
+
placementOffset?: CodegenTypes.WithDefault<CodegenTypes.Double, 16>;
|
|
126
|
+
insetAdjustment?: CodegenTypes.WithDefault<'automatic' | 'never', 'automatic'>;
|
|
127
|
+
dismissThreshold?: CodegenTypes.WithDefault<'half' | 'short', 'half'>;
|
|
116
128
|
|
|
117
129
|
// Boolean properties - match defaults from TrueSheet.types.ts
|
|
118
|
-
grabber?: WithDefault<boolean, true>;
|
|
130
|
+
grabber?: CodegenTypes.WithDefault<boolean, true>;
|
|
119
131
|
grabberOptions?: GrabberOptionsType;
|
|
120
132
|
accessibilityOptions?: AccessibilityOptionsType;
|
|
121
|
-
dismissible?: WithDefault<boolean, true>;
|
|
122
|
-
draggable?: WithDefault<boolean, true>;
|
|
123
|
-
dimmed?: WithDefault<boolean, true>;
|
|
124
|
-
initialDetentAnimated?: WithDefault<boolean, true>;
|
|
133
|
+
dismissible?: CodegenTypes.WithDefault<boolean, true>;
|
|
134
|
+
draggable?: CodegenTypes.WithDefault<boolean, true>;
|
|
135
|
+
dimmed?: CodegenTypes.WithDefault<boolean, true>;
|
|
136
|
+
initialDetentAnimated?: CodegenTypes.WithDefault<boolean, true>;
|
|
137
|
+
// React tag of the scrollable component within the content (see scrollableRef)
|
|
138
|
+
scrollableHandle?: CodegenTypes.WithDefault<CodegenTypes.Int32, -1>;
|
|
125
139
|
scrollableOptions?: ScrollableOptionsType;
|
|
126
140
|
headerOptions?: HeaderOptionsType;
|
|
127
141
|
footerOptions?: FooterOptionsType;
|
|
128
|
-
|
|
142
|
+
foldOptions?: FoldOptionsType;
|
|
143
|
+
presentation?: CodegenTypes.WithDefault<'page' | 'form', 'page'>;
|
|
129
144
|
|
|
130
145
|
// Event handlers
|
|
131
|
-
onMount?: DirectEventHandler<null>;
|
|
132
|
-
onWillPresent?: DirectEventHandler<DetentInfoEventPayload>;
|
|
133
|
-
onDidPresent?: DirectEventHandler<DetentInfoEventPayload>;
|
|
134
|
-
onWillDismiss?: DirectEventHandler<null>;
|
|
135
|
-
onDidDismiss?: DirectEventHandler<null>;
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
+
onMount?: CodegenTypes.DirectEventHandler<null>;
|
|
147
|
+
onWillPresent?: CodegenTypes.DirectEventHandler<DetentInfoEventPayload>;
|
|
148
|
+
onDidPresent?: CodegenTypes.DirectEventHandler<DetentInfoEventPayload>;
|
|
149
|
+
onWillDismiss?: CodegenTypes.DirectEventHandler<null>;
|
|
150
|
+
onDidDismiss?: CodegenTypes.DirectEventHandler<null>;
|
|
151
|
+
onDismissAttempt?: CodegenTypes.DirectEventHandler<null>;
|
|
152
|
+
onDetentChange?: CodegenTypes.DirectEventHandler<DetentInfoEventPayload>;
|
|
153
|
+
onDragBegin?: CodegenTypes.DirectEventHandler<DetentInfoEventPayload>;
|
|
154
|
+
onDragChange?: CodegenTypes.DirectEventHandler<DetentInfoEventPayload>;
|
|
155
|
+
onDragEnd?: CodegenTypes.DirectEventHandler<DetentInfoEventPayload>;
|
|
156
|
+
onPositionChange?: CodegenTypes.DirectEventHandler<PositionChangeEventPayload>;
|
|
157
|
+
onWillFocus?: CodegenTypes.DirectEventHandler<null>;
|
|
158
|
+
onDidFocus?: CodegenTypes.DirectEventHandler<null>;
|
|
159
|
+
onWillBlur?: CodegenTypes.DirectEventHandler<null>;
|
|
160
|
+
onDidBlur?: CodegenTypes.DirectEventHandler<null>;
|
|
161
|
+
onVisibilityChange?: CodegenTypes.DirectEventHandler<Readonly<{ visible: boolean }>>;
|
|
146
162
|
}
|
|
147
163
|
|
|
148
164
|
export default codegenNativeComponent<NativeProps>('TrueSheetView', {
|
package/src/index.ts
CHANGED
package/src/mocks/index.ts
CHANGED
|
@@ -2,6 +2,7 @@ import React, { createElement, isValidElement, type ReactNode } from 'react';
|
|
|
2
2
|
import { View, type ViewProps } from 'react-native';
|
|
3
3
|
|
|
4
4
|
import type { TrueSheetProps, TrueSheetStaticMethods } from '../TrueSheet.types';
|
|
5
|
+
import { TrueSheetBackground } from '../TrueSheetBackground';
|
|
5
6
|
|
|
6
7
|
interface TrueSheetState {
|
|
7
8
|
shouldRenderNativeView: boolean;
|
|
@@ -54,8 +55,15 @@ export class TrueSheet extends React.Component<TrueSheetProps, TrueSheetState> {
|
|
|
54
55
|
}
|
|
55
56
|
|
|
56
57
|
render() {
|
|
57
|
-
const { children, style } = this.props;
|
|
58
|
-
return React.createElement(
|
|
58
|
+
const { children, style, background, backgroundStyle } = this.props;
|
|
59
|
+
return React.createElement(
|
|
60
|
+
View,
|
|
61
|
+
{ style },
|
|
62
|
+
React.createElement(TrueSheetBackground, { background, backgroundStyle }),
|
|
63
|
+
this.renderHeader(),
|
|
64
|
+
children,
|
|
65
|
+
this.renderFooter()
|
|
66
|
+
);
|
|
59
67
|
}
|
|
60
68
|
}
|
|
61
69
|
|
|
@@ -66,6 +74,13 @@ export function TrueSheetPeek({ children, ...rest }: ViewProps) {
|
|
|
66
74
|
return React.createElement(View, rest, children);
|
|
67
75
|
}
|
|
68
76
|
|
|
77
|
+
/**
|
|
78
|
+
* Mock TrueSheetOverlay component for testing.
|
|
79
|
+
*/
|
|
80
|
+
export function TrueSheetOverlay({ children, ...rest }: ViewProps) {
|
|
81
|
+
return React.createElement(View, rest, children);
|
|
82
|
+
}
|
|
83
|
+
|
|
69
84
|
/**
|
|
70
85
|
* Mock TrueSheetProvider for testing.
|
|
71
86
|
*/
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import type { ParamListBase } from '
|
|
2
|
-
|
|
3
|
-
import type { TrueSheetNavigationProp } from '../navigation/types';
|
|
1
|
+
import type { ParamListBase } from '../navigation/expo-router/base-types';
|
|
2
|
+
import type { TrueSheetNavigationProp } from '../navigation/expo-router/types';
|
|
4
3
|
import {
|
|
5
4
|
TrueSheetActions,
|
|
6
5
|
useTrueSheetNavigation as useTrueSheetNavigationMock,
|
|
@@ -22,8 +21,10 @@ export const Sheet = Object.assign(
|
|
|
22
21
|
* Mock useTrueSheetNavigation hook for testing.
|
|
23
22
|
*/
|
|
24
23
|
export const useTrueSheetNavigation = jest.fn(
|
|
24
|
+
// Double cast: the shared mock is typed against React Navigation, this entry
|
|
25
|
+
// against Expo Router's vendored copy — identical shapes, unrelated declarations
|
|
25
26
|
<T extends ParamListBase = ParamListBase>(): TrueSheetNavigationProp<T> =>
|
|
26
|
-
useTrueSheetNavigationMock() as TrueSheetNavigationProp<T>
|
|
27
|
+
useTrueSheetNavigationMock() as unknown as TrueSheetNavigationProp<T>
|
|
27
28
|
);
|
|
28
29
|
|
|
29
30
|
export { TrueSheetActions };
|
|
@@ -37,4 +38,4 @@ export type {
|
|
|
37
38
|
TrueSheetNavigationProp,
|
|
38
39
|
TrueSheetNavigationState,
|
|
39
40
|
TrueSheetScreenProps,
|
|
40
|
-
} from '../navigation/types';
|
|
41
|
+
} from '../navigation/expo-router/types';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base navigation types for the React Navigation entry point.
|
|
3
|
+
*
|
|
4
|
+
* The Expo Router entry has its own copy sourced from `expo-router/react-navigation`
|
|
5
|
+
* (see `./expo-router/base-types`) because Expo Router apps never install
|
|
6
|
+
* `@react-navigation/*` — importing it there would silently resolve to `any`.
|
|
7
|
+
*/
|
|
8
|
+
export type {
|
|
9
|
+
DefaultNavigatorOptions,
|
|
10
|
+
Descriptor,
|
|
11
|
+
NavigationAction,
|
|
12
|
+
NavigationHelpers,
|
|
13
|
+
NavigationProp,
|
|
14
|
+
NavigationState,
|
|
15
|
+
ParamListBase,
|
|
16
|
+
RouteProp,
|
|
17
|
+
Router,
|
|
18
|
+
StackActionHelpers,
|
|
19
|
+
StackRouterOptions,
|
|
20
|
+
} from '@react-navigation/core';
|