@lodev09/react-native-true-sheet 4.0.0-beta.0 → 4.0.0-beta.1
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/LICENSE +1 -1
- package/README.md +42 -31
- package/RNTrueSheet.podspec +10 -2
- package/android/build.gradle +2 -1
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContainerView.kt +174 -49
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContainerViewManager.kt +7 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentView.kt +371 -18
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentViewManager.kt +14 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetFooterView.kt +150 -21
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetFooterViewManager.kt +14 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetHeaderView.kt +38 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetHeaderViewManager.kt +28 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetModule.kt +84 -24
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetPackage.kt +5 -4
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetPeekView.kt +72 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetPeekViewManager.kt +33 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetStateUpdater.kt +45 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +526 -231
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewController.kt +1217 -603
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt +136 -29
- package/android/src/main/java/com/lodev09/truesheet/core/RNScreensEventObserver.kt +63 -0
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetBottomSheetBehavior.kt +36 -0
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetBottomSheetView.kt +255 -0
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetCoordinatorLayout.kt +303 -0
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetDetentCalculator.kt +277 -0
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetDimView.kt +162 -0
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetGrabberView.kt +180 -0
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetKeyboardObserver.kt +207 -0
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetStackManager.kt +220 -0
- package/android/src/main/java/com/lodev09/truesheet/events/TrueSheetDragEvents.kt +71 -0
- package/android/src/main/java/com/lodev09/truesheet/events/TrueSheetFocusEvents.kt +65 -0
- package/android/src/main/java/com/lodev09/truesheet/events/TrueSheetLifecycleEvents.kt +112 -0
- package/android/src/main/java/com/lodev09/truesheet/events/TrueSheetStateEvents.kt +56 -0
- package/android/src/main/java/com/lodev09/truesheet/utils/KeyboardUtils.kt +84 -0
- package/android/src/main/java/com/lodev09/truesheet/utils/ScreenUtils.kt +93 -67
- package/android/src/main/java/com/lodev09/truesheet/utils/ViewUtils.kt +30 -0
- package/android/src/main/jni/CMakeLists.txt +63 -0
- package/android/src/main/jni/TrueSheetSpec.h +19 -0
- package/android/src/main/jni/TrueSheetStateUpdater.cpp +96 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewComponentDescriptor.h +24 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.cpp +43 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.h +28 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewState.cpp +11 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewState.h +37 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewComponentDescriptor.h +24 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.cpp +56 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.h +28 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewState.cpp +11 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewState.h +41 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetInsets.cpp +18 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetInsets.h +16 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewComponentDescriptor.h +28 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewShadowNode.cpp +61 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewShadowNode.h +45 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewState.cpp +23 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewState.h +52 -0
- package/ios/TrueSheetContainerView.h +81 -6
- package/ios/TrueSheetContainerView.mm +275 -21
- package/ios/TrueSheetContentView.h +38 -1
- package/ios/TrueSheetContentView.mm +413 -43
- package/ios/TrueSheetFooterView.h +27 -2
- package/ios/TrueSheetFooterView.mm +141 -35
- package/ios/{events/OnDidDismissEvent.h → TrueSheetHeaderView.h} +10 -7
- package/ios/TrueSheetHeaderView.mm +64 -0
- package/ios/TrueSheetModule.mm +92 -5
- package/ios/TrueSheetPeekView.h +32 -0
- package/ios/TrueSheetPeekView.mm +99 -0
- package/ios/TrueSheetView.h +7 -15
- package/ios/TrueSheetView.mm +633 -215
- package/ios/TrueSheetViewController.h +84 -16
- package/ios/TrueSheetViewController.mm +1136 -333
- package/ios/core/RNScreensEventObserver.h +46 -0
- package/ios/core/RNScreensEventObserver.mm +280 -0
- package/ios/core/TrueSheetBlurView.h +27 -0
- package/ios/core/TrueSheetBlurView.mm +82 -0
- package/ios/core/TrueSheetDetentCalculator.h +107 -0
- package/ios/core/TrueSheetDetentCalculator.mm +197 -0
- package/ios/core/TrueSheetGrabberView.h +72 -0
- package/ios/core/TrueSheetGrabberView.mm +178 -0
- package/ios/core/TrueSheetKeyboardObserver.h +39 -0
- package/ios/core/TrueSheetKeyboardObserver.mm +112 -0
- package/ios/events/TrueSheetDragEvents.h +39 -0
- package/ios/events/TrueSheetDragEvents.mm +62 -0
- package/ios/events/{OnPositionChangeEvent.h → TrueSheetFocusEvents.h} +8 -5
- package/ios/events/TrueSheetFocusEvents.mm +49 -0
- package/ios/events/TrueSheetLifecycleEvents.h +40 -0
- package/ios/events/TrueSheetLifecycleEvents.mm +71 -0
- package/ios/events/TrueSheetStateEvents.h +35 -0
- package/ios/events/TrueSheetStateEvents.mm +49 -0
- package/ios/tvos/TrueSheetStubs.mm +154 -0
- package/ios/{events/OnMountEvent.h → utils/BlurUtil.h} +5 -7
- package/ios/utils/BlurUtil.mm +69 -0
- package/ios/utils/GestureUtil.h +7 -0
- package/ios/utils/GestureUtil.mm +12 -0
- package/ios/utils/PlatformUtil.h +15 -0
- package/ios/utils/UIView+FirstResponder.h +15 -0
- package/ios/utils/UIView+FirstResponder.mm +26 -0
- package/ios/{events/OnWillDismissEvent.h → utils/UIView+ScrollEdgeInteraction.h} +6 -7
- package/ios/utils/UIView+ScrollEdgeInteraction.mm +62 -0
- package/ios/utils/WindowUtil.mm +17 -1
- package/lib/module/TrueSheet.js +224 -64
- package/lib/module/TrueSheet.js.map +1 -1
- package/lib/module/TrueSheet.web.js +1201 -0
- package/lib/module/TrueSheet.web.js.map +1 -0
- package/lib/module/TrueSheetPeek.js +15 -0
- package/lib/module/TrueSheetPeek.js.map +1 -0
- package/lib/module/TrueSheetPeek.web.js +55 -0
- package/lib/module/TrueSheetPeek.web.js.map +1 -0
- package/lib/module/TrueSheetProvider.js +28 -0
- package/lib/module/TrueSheetProvider.js.map +1 -0
- package/lib/module/TrueSheetProvider.web.js +157 -0
- package/lib/module/TrueSheetProvider.web.js.map +1 -0
- package/lib/module/fabric/TrueSheetContainerViewNativeComponent.ts +1 -1
- package/lib/module/fabric/TrueSheetContentViewNativeComponent.ts +5 -1
- package/lib/module/fabric/TrueSheetFooterViewNativeComponent.ts +10 -2
- package/lib/module/fabric/TrueSheetHeaderViewNativeComponent.ts +8 -0
- package/lib/module/fabric/TrueSheetPeekViewNativeComponent.ts +8 -0
- package/lib/module/fabric/TrueSheetViewNativeComponent.ts +105 -18
- package/lib/module/index.js +3 -3
- package/lib/module/index.js.map +1 -1
- package/lib/module/mocks/index.js +93 -0
- package/lib/module/mocks/index.js.map +1 -0
- package/lib/module/mocks/navigation.js +85 -0
- package/lib/module/mocks/navigation.js.map +1 -0
- package/lib/module/mocks/reanimated.js +91 -0
- package/lib/module/mocks/reanimated.js.map +1 -0
- package/lib/module/navigation/TrueSheetRouter.js +170 -0
- package/lib/module/navigation/TrueSheetRouter.js.map +1 -0
- package/lib/module/navigation/TrueSheetView.js +71 -0
- package/lib/module/navigation/TrueSheetView.js.map +1 -0
- package/lib/module/navigation/createTrueSheetNavigator.js +63 -0
- package/lib/module/navigation/createTrueSheetNavigator.js.map +1 -0
- package/lib/module/navigation/index.js +6 -0
- package/lib/module/navigation/index.js.map +1 -0
- package/lib/module/navigation/screen/ReanimatedTrueSheetScreen.js +56 -0
- package/lib/module/navigation/screen/ReanimatedTrueSheetScreen.js.map +1 -0
- package/lib/module/navigation/screen/TrueSheetScreen.js +49 -0
- package/lib/module/navigation/screen/TrueSheetScreen.js.map +1 -0
- package/lib/module/navigation/screen/index.js +5 -0
- package/lib/module/navigation/screen/index.js.map +1 -0
- package/lib/module/navigation/screen/types.js +4 -0
- package/lib/module/navigation/screen/types.js.map +1 -0
- package/lib/module/navigation/screen/useSheetScreenState.js +68 -0
- package/lib/module/navigation/screen/useSheetScreenState.js.map +1 -0
- package/lib/module/navigation/types.js +4 -0
- package/lib/module/navigation/types.js.map +1 -0
- package/lib/module/navigation/useTrueSheetNavigation.js +24 -0
- package/lib/module/navigation/useTrueSheetNavigation.js.map +1 -0
- package/lib/module/reanimated/ReanimatedTrueSheet.js +15 -9
- package/lib/module/reanimated/ReanimatedTrueSheet.js.map +1 -1
- package/lib/module/reanimated/ReanimatedTrueSheet.web.js +81 -0
- package/lib/module/reanimated/ReanimatedTrueSheet.web.js.map +1 -0
- package/lib/module/reanimated/ReanimatedTrueSheetProvider.js +4 -2
- package/lib/module/reanimated/ReanimatedTrueSheetProvider.js.map +1 -1
- package/lib/module/reanimated/index.js +2 -2
- package/lib/module/reanimated/index.js.map +1 -1
- package/lib/module/reanimated/useReanimatedPositionChangeHandler.web.js +20 -0
- package/lib/module/reanimated/useReanimatedPositionChangeHandler.web.js.map +1 -0
- package/lib/module/specs/NativeTrueSheetModule.js.map +1 -1
- package/lib/module/web/constants.js +16 -0
- package/lib/module/web/constants.js.map +1 -0
- package/lib/module/web/vaul/README.md +9 -0
- package/lib/module/web/vaul/browser.js +30 -0
- package/lib/module/web/vaul/browser.js.map +1 -0
- package/lib/module/web/vaul/constants.js +15 -0
- package/lib/module/web/vaul/constants.js.map +1 -0
- package/lib/module/web/vaul/context.js +59 -0
- package/lib/module/web/vaul/context.js.map +1 -0
- package/lib/module/web/vaul/helpers.js +93 -0
- package/lib/module/web/vaul/helpers.js.map +1 -0
- package/lib/module/web/vaul/index.js +1309 -0
- package/lib/module/web/vaul/index.js.map +1 -0
- package/lib/module/web/vaul/style.css +287 -0
- package/lib/module/web/vaul/style.css.d.js +2 -0
- package/lib/module/web/vaul/style.css.d.js.map +1 -0
- package/lib/module/web/vaul/types.js +2 -0
- package/lib/module/web/vaul/types.js.map +1 -0
- package/lib/module/web/vaul/use-composed-refs.js +34 -0
- package/lib/module/web/vaul/use-composed-refs.js.map +1 -0
- package/lib/module/web/vaul/use-controllable-state.js +54 -0
- package/lib/module/web/vaul/use-controllable-state.js.map +1 -0
- package/lib/module/web/vaul/use-position-fixed.js +123 -0
- package/lib/module/web/vaul/use-position-fixed.js.map +1 -0
- package/lib/module/web/vaul/use-prevent-scroll.js +258 -0
- package/lib/module/web/vaul/use-prevent-scroll.js.map +1 -0
- package/lib/module/web/vaul/use-scale-background.js +57 -0
- package/lib/module/web/vaul/use-scale-background.js.map +1 -0
- package/lib/module/web/vaul/use-snap-points.js +305 -0
- package/lib/module/web/vaul/use-snap-points.js.map +1 -0
- package/lib/typescript/src/TrueSheet.d.ts +51 -14
- package/lib/typescript/src/TrueSheet.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheet.types.d.ts +463 -54
- package/lib/typescript/src/TrueSheet.types.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheet.web.d.ts +5 -0
- package/lib/typescript/src/TrueSheet.web.d.ts.map +1 -0
- package/lib/typescript/src/TrueSheetPeek.d.ts +9 -0
- package/lib/typescript/src/TrueSheetPeek.d.ts.map +1 -0
- package/lib/typescript/src/TrueSheetPeek.web.d.ts +28 -0
- package/lib/typescript/src/TrueSheetPeek.web.d.ts.map +1 -0
- package/lib/typescript/src/TrueSheetProvider.d.ts +18 -0
- package/lib/typescript/src/TrueSheetProvider.d.ts.map +1 -0
- package/lib/typescript/src/TrueSheetProvider.web.d.ts +27 -0
- package/lib/typescript/src/TrueSheetProvider.web.d.ts.map +1 -0
- package/lib/typescript/src/fabric/TrueSheetContainerViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/fabric/TrueSheetContentViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/fabric/TrueSheetFooterViewNativeComponent.d.ts +2 -0
- package/lib/typescript/src/fabric/TrueSheetFooterViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/fabric/TrueSheetHeaderViewNativeComponent.d.ts +6 -0
- package/lib/typescript/src/fabric/TrueSheetHeaderViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/fabric/TrueSheetPeekViewNativeComponent.d.ts +6 -0
- package/lib/typescript/src/fabric/TrueSheetPeekViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts +67 -16
- package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +2 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/mocks/index.d.ts +43 -0
- package/lib/typescript/src/mocks/index.d.ts.map +1 -0
- package/lib/typescript/src/mocks/navigation.d.ts +66 -0
- package/lib/typescript/src/mocks/navigation.d.ts.map +1 -0
- package/lib/typescript/src/mocks/reanimated.d.ts +48 -0
- package/lib/typescript/src/mocks/reanimated.d.ts.map +1 -0
- package/lib/typescript/src/navigation/TrueSheetRouter.d.ts +57 -0
- package/lib/typescript/src/navigation/TrueSheetRouter.d.ts.map +1 -0
- package/lib/typescript/src/navigation/TrueSheetView.d.ts +10 -0
- package/lib/typescript/src/navigation/TrueSheetView.d.ts.map +1 -0
- package/lib/typescript/src/navigation/createTrueSheetNavigator.d.ts +35 -0
- package/lib/typescript/src/navigation/createTrueSheetNavigator.d.ts.map +1 -0
- package/lib/typescript/src/navigation/index.d.ts +6 -0
- package/lib/typescript/src/navigation/index.d.ts.map +1 -0
- package/lib/typescript/src/navigation/screen/ReanimatedTrueSheetScreen.d.ts +3 -0
- package/lib/typescript/src/navigation/screen/ReanimatedTrueSheetScreen.d.ts.map +1 -0
- package/lib/typescript/src/navigation/screen/TrueSheetScreen.d.ts +3 -0
- package/lib/typescript/src/navigation/screen/TrueSheetScreen.d.ts.map +1 -0
- package/lib/typescript/src/navigation/screen/index.d.ts +4 -0
- package/lib/typescript/src/navigation/screen/index.d.ts.map +1 -0
- package/lib/typescript/src/navigation/screen/types.d.ts +15 -0
- package/lib/typescript/src/navigation/screen/types.d.ts.map +1 -0
- package/lib/typescript/src/navigation/screen/useSheetScreenState.d.ts +35 -0
- package/lib/typescript/src/navigation/screen/useSheetScreenState.d.ts.map +1 -0
- package/lib/typescript/src/navigation/types.d.ts +153 -0
- package/lib/typescript/src/navigation/types.d.ts.map +1 -0
- package/lib/typescript/src/navigation/useTrueSheetNavigation.d.ts +23 -0
- package/lib/typescript/src/navigation/useTrueSheetNavigation.d.ts.map +1 -0
- package/lib/typescript/src/reanimated/ReanimatedTrueSheet.d.ts.map +1 -1
- package/lib/typescript/src/reanimated/ReanimatedTrueSheet.web.d.ts +41 -0
- package/lib/typescript/src/reanimated/ReanimatedTrueSheet.web.d.ts.map +1 -0
- package/lib/typescript/src/reanimated/ReanimatedTrueSheetProvider.d.ts +8 -2
- package/lib/typescript/src/reanimated/ReanimatedTrueSheetProvider.d.ts.map +1 -1
- package/lib/typescript/src/reanimated/useReanimatedPositionChangeHandler.web.d.ts +15 -0
- package/lib/typescript/src/reanimated/useReanimatedPositionChangeHandler.web.d.ts.map +1 -0
- package/lib/typescript/src/specs/NativeTrueSheetModule.d.ts +25 -3
- package/lib/typescript/src/specs/NativeTrueSheetModule.d.ts.map +1 -1
- package/lib/typescript/src/web/constants.d.ts +14 -0
- package/lib/typescript/src/web/constants.d.ts.map +1 -0
- package/lib/typescript/src/web/vaul/browser.d.ts +8 -0
- package/lib/typescript/src/web/vaul/browser.d.ts.map +1 -0
- package/lib/typescript/src/web/vaul/constants.d.ts +13 -0
- package/lib/typescript/src/web/vaul/constants.d.ts.map +1 -0
- package/lib/typescript/src/web/vaul/context.d.ts +53 -0
- package/lib/typescript/src/web/vaul/context.d.ts.map +1 -0
- package/lib/typescript/src/web/vaul/helpers.d.ts +17 -0
- package/lib/typescript/src/web/vaul/helpers.d.ts.map +1 -0
- package/lib/typescript/src/web/vaul/index.d.ts +228 -0
- package/lib/typescript/src/web/vaul/index.d.ts.map +1 -0
- package/lib/typescript/src/web/vaul/types.d.ts +7 -0
- package/lib/typescript/src/web/vaul/types.d.ts.map +1 -0
- package/lib/typescript/src/web/vaul/use-composed-refs.d.ts +14 -0
- package/lib/typescript/src/web/vaul/use-composed-refs.d.ts.map +1 -0
- package/lib/typescript/src/web/vaul/use-controllable-state.d.ts +9 -0
- package/lib/typescript/src/web/vaul/use-controllable-state.d.ts.map +1 -0
- package/lib/typescript/src/web/vaul/use-position-fixed.d.ts +19 -0
- package/lib/typescript/src/web/vaul/use-position-fixed.d.ts.map +1 -0
- package/lib/typescript/src/web/vaul/use-prevent-scroll.d.ts +18 -0
- package/lib/typescript/src/web/vaul/use-prevent-scroll.d.ts.map +1 -0
- package/lib/typescript/src/web/vaul/use-scale-background.d.ts +2 -0
- package/lib/typescript/src/web/vaul/use-scale-background.d.ts.map +1 -0
- package/lib/typescript/src/web/vaul/use-snap-points.d.ts +38 -0
- package/lib/typescript/src/web/vaul/use-snap-points.d.ts.map +1 -0
- package/package.json +78 -34
- package/react-native.config.js +9 -2
- package/src/TrueSheet.tsx +276 -60
- package/src/TrueSheet.types.ts +525 -71
- package/src/TrueSheet.web.tsx +1366 -0
- package/src/TrueSheetPeek.tsx +11 -0
- package/src/TrueSheetPeek.web.tsx +63 -0
- package/src/TrueSheetProvider.tsx +33 -0
- package/src/TrueSheetProvider.web.tsx +220 -0
- package/src/fabric/TrueSheetContainerViewNativeComponent.ts +1 -1
- package/src/fabric/TrueSheetContentViewNativeComponent.ts +5 -1
- package/src/fabric/TrueSheetFooterViewNativeComponent.ts +10 -2
- package/src/fabric/TrueSheetHeaderViewNativeComponent.ts +8 -0
- package/src/fabric/TrueSheetPeekViewNativeComponent.ts +8 -0
- package/src/fabric/TrueSheetViewNativeComponent.ts +105 -18
- package/src/index.ts +2 -2
- package/src/mocks/index.ts +89 -0
- package/src/mocks/navigation.ts +72 -0
- package/src/mocks/reanimated.ts +101 -0
- package/src/navigation/TrueSheetRouter.ts +234 -0
- package/src/navigation/TrueSheetView.tsx +99 -0
- package/src/navigation/createTrueSheetNavigator.tsx +93 -0
- package/src/navigation/index.ts +14 -0
- package/src/navigation/screen/ReanimatedTrueSheetScreen.tsx +61 -0
- package/src/navigation/screen/TrueSheetScreen.tsx +54 -0
- package/src/navigation/screen/index.ts +3 -0
- package/src/navigation/screen/types.ts +21 -0
- package/src/navigation/screen/useSheetScreenState.ts +107 -0
- package/src/navigation/types.ts +219 -0
- package/src/navigation/useTrueSheetNavigation.ts +26 -0
- package/src/reanimated/ReanimatedTrueSheet.tsx +12 -7
- package/src/reanimated/ReanimatedTrueSheet.web.tsx +75 -0
- package/src/reanimated/ReanimatedTrueSheetProvider.tsx +12 -8
- package/src/reanimated/useReanimatedPositionChangeHandler.web.ts +31 -0
- package/src/specs/NativeTrueSheetModule.ts +28 -3
- package/src/web/constants.ts +13 -0
- package/src/web/vaul/README.md +9 -0
- package/src/web/vaul/browser.ts +38 -0
- package/src/web/vaul/constants.ts +20 -0
- package/src/web/vaul/context.ts +101 -0
- package/src/web/vaul/helpers.ts +124 -0
- package/src/web/vaul/index.tsx +1740 -0
- package/src/web/vaul/style.css +287 -0
- package/src/web/vaul/style.css.d.ts +1 -0
- package/src/web/vaul/types.ts +7 -0
- package/src/web/vaul/use-composed-refs.ts +35 -0
- package/src/web/vaul/use-controllable-state.ts +66 -0
- package/src/web/vaul/use-position-fixed.ts +147 -0
- package/src/web/vaul/use-prevent-scroll.ts +309 -0
- package/src/web/vaul/use-scale-background.ts +64 -0
- package/src/web/vaul/use-snap-points.ts +455 -0
- package/android/src/main/java/com/lodev09/truesheet/events/DetentChangeEvent.kt +0 -26
- package/android/src/main/java/com/lodev09/truesheet/events/DidDismissEvent.kt +0 -20
- package/android/src/main/java/com/lodev09/truesheet/events/DidPresentEvent.kt +0 -26
- package/android/src/main/java/com/lodev09/truesheet/events/DragBeginEvent.kt +0 -26
- package/android/src/main/java/com/lodev09/truesheet/events/DragChangeEvent.kt +0 -26
- package/android/src/main/java/com/lodev09/truesheet/events/DragEndEvent.kt +0 -26
- package/android/src/main/java/com/lodev09/truesheet/events/MountEvent.kt +0 -20
- package/android/src/main/java/com/lodev09/truesheet/events/PositionChangeEvent.kt +0 -32
- package/android/src/main/java/com/lodev09/truesheet/events/SizeChangeEvent.kt +0 -27
- package/android/src/main/java/com/lodev09/truesheet/events/WillDismissEvent.kt +0 -20
- package/android/src/main/java/com/lodev09/truesheet/events/WillPresentEvent.kt +0 -26
- package/android/src/main/res/values/styles.xml +0 -8
- package/ios/events/OnDetentChangeEvent.h +0 -28
- package/ios/events/OnDetentChangeEvent.mm +0 -30
- package/ios/events/OnDidDismissEvent.mm +0 -25
- package/ios/events/OnDidPresentEvent.h +0 -28
- package/ios/events/OnDidPresentEvent.mm +0 -30
- package/ios/events/OnDragBeginEvent.h +0 -28
- package/ios/events/OnDragBeginEvent.mm +0 -30
- package/ios/events/OnDragChangeEvent.h +0 -28
- package/ios/events/OnDragChangeEvent.mm +0 -30
- package/ios/events/OnDragEndEvent.h +0 -28
- package/ios/events/OnDragEndEvent.mm +0 -30
- package/ios/events/OnMountEvent.mm +0 -25
- package/ios/events/OnPositionChangeEvent.mm +0 -32
- package/ios/events/OnSizeChangeEvent.h +0 -28
- package/ios/events/OnSizeChangeEvent.mm +0 -30
- package/ios/events/OnWillDismissEvent.mm +0 -25
- package/ios/events/OnWillPresentEvent.h +0 -28
- package/ios/events/OnWillPresentEvent.mm +0 -30
- package/ios/utils/LayoutUtil.h +0 -44
- package/ios/utils/LayoutUtil.mm +0 -50
- package/lib/module/TrueSheetGrabber.js +0 -51
- package/lib/module/TrueSheetGrabber.js.map +0 -1
- package/lib/typescript/src/TrueSheetGrabber.d.ts +0 -39
- package/lib/typescript/src/TrueSheetGrabber.d.ts.map +0 -1
- package/src/TrueSheetGrabber.tsx +0 -82
- package/src/__mocks__/index.js +0 -67
package/ios/TrueSheetView.mm
CHANGED
|
@@ -14,59 +14,82 @@
|
|
|
14
14
|
#import "TrueSheetFooterView.h"
|
|
15
15
|
#import "TrueSheetModule.h"
|
|
16
16
|
#import "TrueSheetViewController.h"
|
|
17
|
-
#import "
|
|
18
|
-
#import "events/
|
|
19
|
-
#import "events/
|
|
20
|
-
#import "events/
|
|
21
|
-
#import "events/
|
|
22
|
-
#import "events/OnDragEndEvent.h"
|
|
23
|
-
#import "events/OnMountEvent.h"
|
|
24
|
-
#import "events/OnPositionChangeEvent.h"
|
|
25
|
-
#import "events/OnSizeChangeEvent.h"
|
|
26
|
-
#import "events/OnWillDismissEvent.h"
|
|
27
|
-
#import "events/OnWillPresentEvent.h"
|
|
28
|
-
#import "utils/LayoutUtil.h"
|
|
17
|
+
#import "core/RNScreensEventObserver.h"
|
|
18
|
+
#import "events/TrueSheetDragEvents.h"
|
|
19
|
+
#import "events/TrueSheetFocusEvents.h"
|
|
20
|
+
#import "events/TrueSheetLifecycleEvents.h"
|
|
21
|
+
#import "events/TrueSheetStateEvents.h"
|
|
29
22
|
#import "utils/WindowUtil.h"
|
|
30
23
|
|
|
31
|
-
#import <react/renderer/components/TrueSheetSpec/ComponentDescriptors.h>
|
|
32
24
|
#import <react/renderer/components/TrueSheetSpec/EventEmitters.h>
|
|
33
25
|
#import <react/renderer/components/TrueSheetSpec/Props.h>
|
|
34
26
|
#import <react/renderer/components/TrueSheetSpec/RCTComponentViewHelpers.h>
|
|
27
|
+
#import <react/renderer/components/TrueSheetSpec/TrueSheetInsets.h>
|
|
28
|
+
#import <react/renderer/components/TrueSheetSpec/TrueSheetViewComponentDescriptor.h>
|
|
29
|
+
#import <react/renderer/components/TrueSheetSpec/TrueSheetViewShadowNode.h>
|
|
30
|
+
#import <react/renderer/components/TrueSheetSpec/TrueSheetViewState.h>
|
|
35
31
|
|
|
36
32
|
#import <React/RCTConversions.h>
|
|
37
33
|
#import <React/RCTFabricComponentsPlugins.h>
|
|
34
|
+
#import <React/RCTLog.h>
|
|
38
35
|
#import <React/RCTSurfaceTouchHandler.h>
|
|
39
36
|
#import <React/RCTUtils.h>
|
|
37
|
+
#import <react/renderer/core/State.h>
|
|
40
38
|
|
|
41
39
|
using namespace facebook::react;
|
|
42
40
|
|
|
43
|
-
@interface TrueSheetView () <TrueSheetViewControllerDelegate,
|
|
41
|
+
@interface TrueSheetView () <TrueSheetViewControllerDelegate,
|
|
42
|
+
TrueSheetContainerViewDelegate,
|
|
43
|
+
RNScreensEventObserverDelegate>
|
|
44
44
|
@end
|
|
45
45
|
|
|
46
46
|
@implementation TrueSheetView {
|
|
47
47
|
TrueSheetContainerView *_containerView;
|
|
48
48
|
TrueSheetViewController *_controller;
|
|
49
49
|
RCTSurfaceTouchHandler *_touchHandler;
|
|
50
|
+
TrueSheetViewShadowNode::ConcreteState::Shared _state;
|
|
51
|
+
UIView *_snapshotView;
|
|
52
|
+
CGSize _lastStateSize;
|
|
50
53
|
NSInteger _initialDetentIndex;
|
|
54
|
+
TrueSheetViewInsetAdjustment _insetAdjustment;
|
|
55
|
+
ScrollableOptions *_scrollableOptions;
|
|
56
|
+
BOOL _hasAutoDetent;
|
|
51
57
|
BOOL _initialDetentAnimated;
|
|
58
|
+
BOOL _isSheetUpdatePending;
|
|
59
|
+
BOOL _pendingLayoutUpdate;
|
|
60
|
+
BOOL _didInitiallyPresent;
|
|
61
|
+
BOOL _dismissedByNavigation;
|
|
62
|
+
BOOL _pendingNavigationRepresent;
|
|
63
|
+
BOOL _pendingMountEvent;
|
|
64
|
+
BOOL _pendingSizeChange;
|
|
65
|
+
BOOL _pendingPropsUpdate;
|
|
66
|
+
NSArray *_pendingDetents;
|
|
67
|
+
RNScreensEventObserver *_screensEventObserver;
|
|
52
68
|
}
|
|
53
69
|
|
|
70
|
+
#pragma mark - Initialization
|
|
71
|
+
|
|
54
72
|
- (instancetype)initWithFrame:(CGRect)frame {
|
|
55
73
|
if (self = [super initWithFrame:frame]) {
|
|
56
74
|
static const auto defaultProps = std::make_shared<const TrueSheetViewProps>();
|
|
57
75
|
_props = defaultProps;
|
|
58
76
|
|
|
59
|
-
|
|
77
|
+
self.hidden = YES;
|
|
78
|
+
self.userInteractionEnabled = NO;
|
|
79
|
+
|
|
60
80
|
_controller = [[TrueSheetViewController alloc] init];
|
|
61
81
|
_controller.delegate = self;
|
|
62
82
|
|
|
63
|
-
// Initialize touch handler - will be attached to container when mounted
|
|
64
83
|
_touchHandler = [[RCTSurfaceTouchHandler alloc] init];
|
|
65
|
-
|
|
66
84
|
_containerView = nil;
|
|
67
|
-
|
|
85
|
+
_snapshotView = nil;
|
|
86
|
+
_lastStateSize = CGSizeZero;
|
|
68
87
|
_initialDetentIndex = -1;
|
|
69
88
|
_initialDetentAnimated = YES;
|
|
89
|
+
_isSheetUpdatePending = NO;
|
|
90
|
+
|
|
91
|
+
_screensEventObserver = [[RNScreensEventObserver alloc] init];
|
|
92
|
+
_screensEventObserver.delegate = self;
|
|
70
93
|
}
|
|
71
94
|
return self;
|
|
72
95
|
}
|
|
@@ -74,28 +97,56 @@ using namespace facebook::react;
|
|
|
74
97
|
- (void)didMoveToWindow {
|
|
75
98
|
[super didMoveToWindow];
|
|
76
99
|
|
|
77
|
-
if (!self.window)
|
|
100
|
+
if (!self.window)
|
|
78
101
|
return;
|
|
79
|
-
}
|
|
80
102
|
|
|
81
|
-
// Register this view with the TurboModule when added to window
|
|
82
|
-
// This ensures the tag is properly set by the framework
|
|
83
103
|
if (self.tag > 0) {
|
|
84
104
|
[TrueSheetModule registerView:self withTag:@(self.tag)];
|
|
85
105
|
}
|
|
106
|
+
|
|
107
|
+
if (_pendingNavigationRepresent && !_controller.isPresented) {
|
|
108
|
+
_pendingNavigationRepresent = NO;
|
|
109
|
+
[self presentAtIndex:_controller.activeDetentIndex animated:YES completion:nil];
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (_initialDetentIndex >= 0 && !_didInitiallyPresent) {
|
|
114
|
+
UIViewController *vc = [self findPresentingViewController];
|
|
115
|
+
|
|
116
|
+
// Only present if the view controller is in the same window and not being dismissed
|
|
117
|
+
if (vc && vc.view.window == self.window && !_controller.isBeingDismissed) {
|
|
118
|
+
_didInitiallyPresent = YES;
|
|
119
|
+
[self presentAtIndex:_initialDetentIndex animated:_initialDetentAnimated completion:nil];
|
|
120
|
+
} else {
|
|
121
|
+
// Animate next time when sheet finally moves to the correct window
|
|
122
|
+
_initialDetentAnimated = YES;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
86
125
|
}
|
|
87
126
|
|
|
88
127
|
- (void)dealloc {
|
|
89
|
-
|
|
128
|
+
[_screensEventObserver stopObserving];
|
|
129
|
+
_screensEventObserver = nil;
|
|
130
|
+
|
|
90
131
|
if (_controller && _controller.presentingViewController) {
|
|
91
|
-
|
|
132
|
+
// Find the root presenting controller to dismiss the entire stack
|
|
133
|
+
UIViewController *root = _controller.presentingViewController;
|
|
134
|
+
while (root.presentingViewController != nil) {
|
|
135
|
+
root = root.presentingViewController;
|
|
136
|
+
}
|
|
137
|
+
[root dismissViewControllerAnimated:YES completion:nil];
|
|
92
138
|
}
|
|
93
139
|
|
|
94
|
-
|
|
140
|
+
_didInitiallyPresent = NO;
|
|
141
|
+
_dismissedByNavigation = NO;
|
|
142
|
+
_pendingNavigationRepresent = NO;
|
|
143
|
+
|
|
95
144
|
_controller.delegate = nil;
|
|
96
145
|
_controller = nil;
|
|
97
146
|
|
|
98
|
-
|
|
147
|
+
[_snapshotView removeFromSuperview];
|
|
148
|
+
_snapshotView = nil;
|
|
149
|
+
|
|
99
150
|
[TrueSheetModule unregisterViewWithTag:@(self.tag)];
|
|
100
151
|
}
|
|
101
152
|
|
|
@@ -105,319 +156,686 @@ using namespace facebook::react;
|
|
|
105
156
|
return concreteComponentDescriptorProvider<TrueSheetViewComponentDescriptor>();
|
|
106
157
|
}
|
|
107
158
|
|
|
159
|
+
- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps {
|
|
160
|
+
[super updateProps:props oldProps:oldProps];
|
|
161
|
+
|
|
162
|
+
const auto &newProps = *std::static_pointer_cast<TrueSheetViewProps const>(props);
|
|
163
|
+
|
|
164
|
+
// Detents (-1 represents "auto")
|
|
165
|
+
NSMutableArray *detents = [NSMutableArray new];
|
|
166
|
+
_hasAutoDetent = NO;
|
|
167
|
+
for (const auto &detent : newProps.detents) {
|
|
168
|
+
[detents addObject:@(detent)];
|
|
169
|
+
if (detent == -1) {
|
|
170
|
+
_hasAutoDetent = YES;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (oldProps) {
|
|
175
|
+
const auto &prevProps = *std::static_pointer_cast<TrueSheetViewProps const>(oldProps);
|
|
176
|
+
if (newProps.detents != prevProps.detents || newProps.insetAdjustment != prevProps.insetAdjustment) {
|
|
177
|
+
_pendingLayoutUpdate = YES;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (_controller.isBeingPresented) {
|
|
182
|
+
_pendingDetents = detents;
|
|
183
|
+
} else {
|
|
184
|
+
_controller.detents = detents;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Background color
|
|
188
|
+
_controller.backgroundColor = RCTUIColorFromSharedColor(newProps.backgroundColor);
|
|
189
|
+
|
|
190
|
+
// Blur tint
|
|
191
|
+
_controller.backgroundBlur = newProps.backgroundBlur;
|
|
192
|
+
|
|
193
|
+
// Blur options
|
|
194
|
+
const auto &blurOpts = newProps.blurOptions;
|
|
195
|
+
_controller.blurIntensity = blurOpts.intensity >= 0 ? @(blurOpts.intensity) : nil;
|
|
196
|
+
_controller.blurInteraction = blurOpts.interaction;
|
|
197
|
+
|
|
198
|
+
// Corner radius
|
|
199
|
+
_controller.cornerRadius = newProps.cornerRadius < 0 ? nil : @(newProps.cornerRadius);
|
|
200
|
+
|
|
201
|
+
// Content height
|
|
202
|
+
_controller.maxContentHeight = newProps.maxContentHeight != 0.0 ? @(newProps.maxContentHeight) : nil;
|
|
203
|
+
|
|
204
|
+
// Content width
|
|
205
|
+
_controller.maxContentWidth = newProps.maxContentWidth != 0.0 ? @(newProps.maxContentWidth) : nil;
|
|
206
|
+
|
|
207
|
+
// Anchor
|
|
208
|
+
_controller.anchor = newProps.anchor;
|
|
209
|
+
|
|
210
|
+
_controller.grabber = newProps.grabber;
|
|
211
|
+
|
|
212
|
+
// Grabber options - check if any non-default values are set
|
|
213
|
+
const auto &grabberOpts = newProps.grabberOptions;
|
|
214
|
+
UIColor *grabberColor = RCTUIColorFromSharedColor(grabberOpts.color);
|
|
215
|
+
BOOL hasGrabberOptions = grabberOpts.width > 0 || grabberOpts.height > 0 || grabberOpts.topMargin > 0 ||
|
|
216
|
+
grabberOpts.cornerRadius >= 0 || grabberColor != nil || !grabberOpts.adaptive;
|
|
217
|
+
|
|
218
|
+
if (hasGrabberOptions) {
|
|
219
|
+
GrabberOptions *options = [[GrabberOptions alloc] init];
|
|
220
|
+
if (grabberOpts.width > 0)
|
|
221
|
+
options.width = @(grabberOpts.width);
|
|
222
|
+
if (grabberOpts.height > 0)
|
|
223
|
+
options.height = @(grabberOpts.height);
|
|
224
|
+
if (grabberOpts.topMargin > 0)
|
|
225
|
+
options.topMargin = @(grabberOpts.topMargin);
|
|
226
|
+
if (grabberOpts.cornerRadius >= 0)
|
|
227
|
+
options.cornerRadius = @(grabberOpts.cornerRadius);
|
|
228
|
+
if (grabberColor)
|
|
229
|
+
options.color = grabberColor;
|
|
230
|
+
options.adaptive = grabberOpts.adaptive;
|
|
231
|
+
_controller.grabberOptions = options;
|
|
232
|
+
} else {
|
|
233
|
+
_controller.grabberOptions = nil;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Accessibility options - applied to the custom grabber
|
|
237
|
+
_controller.accessibilityOptions = newProps.accessibilityOptions;
|
|
238
|
+
|
|
239
|
+
_controller.presentation = newProps.presentation;
|
|
240
|
+
_controller.dismissible = newProps.dismissible;
|
|
241
|
+
_controller.draggable = newProps.draggable;
|
|
242
|
+
_controller.dimmed = newProps.dimmed;
|
|
243
|
+
|
|
244
|
+
if (newProps.dimmedDetentIndex >= 0) {
|
|
245
|
+
_controller.dimmedDetentIndex = @(newProps.dimmedDetentIndex);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
_initialDetentIndex = newProps.initialDetentIndex;
|
|
249
|
+
_initialDetentAnimated = newProps.initialDetentAnimated;
|
|
250
|
+
|
|
251
|
+
const auto &scrollableOpts = newProps.scrollableOptions;
|
|
252
|
+
BOOL scrollingExpandsSheet = scrollableOpts.scrollingExpandsSheet;
|
|
253
|
+
auto topEdgeEffect = scrollableOpts.topScrollEdgeEffect;
|
|
254
|
+
auto bottomEdgeEffect = scrollableOpts.bottomScrollEdgeEffect;
|
|
255
|
+
BOOL hasScrollableOptions = scrollableOpts.keyboardScrollOffset > 0 || !scrollingExpandsSheet ||
|
|
256
|
+
topEdgeEffect != TrueSheetViewTopScrollEdgeEffect::Hidden ||
|
|
257
|
+
bottomEdgeEffect != TrueSheetViewBottomScrollEdgeEffect::Hidden;
|
|
258
|
+
|
|
259
|
+
if (hasScrollableOptions) {
|
|
260
|
+
ScrollableOptions *options = [[ScrollableOptions alloc] init];
|
|
261
|
+
options.keyboardScrollOffset = scrollableOpts.keyboardScrollOffset;
|
|
262
|
+
options.scrollingExpandsSheet = scrollingExpandsSheet;
|
|
263
|
+
options.topScrollEdgeEffect = topEdgeEffect;
|
|
264
|
+
options.bottomScrollEdgeEffect = bottomEdgeEffect;
|
|
265
|
+
_scrollableOptions = options;
|
|
266
|
+
} else {
|
|
267
|
+
_scrollableOptions = nil;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
_controller.scrollingExpandsSheet = scrollingExpandsSheet;
|
|
271
|
+
|
|
272
|
+
_controller.absoluteHeader = newProps.headerOptions.position == TrueSheetViewPosition::Absolute;
|
|
273
|
+
_controller.absoluteFooter = newProps.footerOptions.footerPosition == TrueSheetViewFooterPosition::Absolute;
|
|
274
|
+
|
|
275
|
+
CGFloat footerKeyboardOffset = newProps.footerOptions.keyboardOffset;
|
|
276
|
+
if (_controller.footerKeyboardOffset != footerKeyboardOffset) {
|
|
277
|
+
_controller.footerKeyboardOffset = footerKeyboardOffset;
|
|
278
|
+
[_containerView updateFooterKeyboardOffset];
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
_insetAdjustment = newProps.insetAdjustment;
|
|
282
|
+
_controller.insetAdjustment = _insetAdjustment;
|
|
283
|
+
|
|
284
|
+
[self setupScrollable];
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
- (void)updateState:(const State::Shared &)state oldState:(const State::Shared &)oldState {
|
|
288
|
+
_state = std::static_pointer_cast<TrueSheetViewShadowNode::ConcreteState const>(state);
|
|
289
|
+
|
|
290
|
+
if (_controller && !_controller.isStackedBehindChild) {
|
|
291
|
+
CGSize size = _controller.view.frame.size;
|
|
292
|
+
if (size.width < 1 || size.height < 1) {
|
|
293
|
+
// Pre-present the controller has no layout yet. Seed with screen
|
|
294
|
+
// dimensions so content (e.g. a FlatList viewport) can lay out and
|
|
295
|
+
// measure before the sheet presents (parity with Android).
|
|
296
|
+
UIWindow *window = [WindowUtil keyWindow];
|
|
297
|
+
size = window ? window.bounds.size : UIScreen.mainScreen.bounds.size;
|
|
298
|
+
}
|
|
299
|
+
[self viewControllerDidChangeSize:size];
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Updates Fabric state with container dimensions for Yoga layout.
|
|
305
|
+
*/
|
|
306
|
+
- (void)updateStateWithSize:(CGSize)size {
|
|
307
|
+
if (!_state)
|
|
308
|
+
return;
|
|
309
|
+
|
|
310
|
+
if (fabs(size.width - _lastStateSize.width) < 0.5 && fabs(size.height - _lastStateSize.height) < 0.5)
|
|
311
|
+
return;
|
|
312
|
+
|
|
313
|
+
_lastStateSize = size;
|
|
314
|
+
|
|
315
|
+
auto stateData = _state->getData();
|
|
316
|
+
stateData.containerWidth = static_cast<float>(size.width);
|
|
317
|
+
stateData.containerHeight = static_cast<float>(size.height);
|
|
318
|
+
|
|
319
|
+
// RN 0.82+ processes immediate state updates in the same layout pass, so Yoga
|
|
320
|
+
// resizes the container synchronously with the sheet (e.g. inside UIKit's
|
|
321
|
+
// animation block during detent transitions).
|
|
322
|
+
_state->updateState(std::move(stateData), facebook::react::EventQueue::UpdateMode::unstable_Immediate);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
- (void)finalizeUpdates:(RNComponentViewUpdateMask)updateMask {
|
|
326
|
+
[super finalizeUpdates:updateMask];
|
|
327
|
+
|
|
328
|
+
// Emit pending mount event now that eventEmitter is available
|
|
329
|
+
if (_pendingMountEvent && (updateMask & RNComponentViewUpdateMaskEventEmitter)) {
|
|
330
|
+
_pendingMountEvent = NO;
|
|
331
|
+
[TrueSheetLifecycleEvents emitMount:_eventEmitter];
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
if (!(updateMask & RNComponentViewUpdateMaskProps) || !_controller)
|
|
335
|
+
return;
|
|
336
|
+
|
|
337
|
+
[self setupScrollable];
|
|
338
|
+
|
|
339
|
+
if (_controller.isPresented) {
|
|
340
|
+
[self applySheetPropsUpdate];
|
|
341
|
+
} else if (_controller.isBeingPresented) {
|
|
342
|
+
_pendingPropsUpdate = YES;
|
|
343
|
+
} else if (_initialDetentIndex >= 0) {
|
|
344
|
+
_pendingLayoutUpdate = NO;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
- (void)prepareForRecycle {
|
|
349
|
+
[super prepareForRecycle];
|
|
350
|
+
|
|
351
|
+
[TrueSheetModule unregisterViewWithTag:@(self.tag)];
|
|
352
|
+
|
|
353
|
+
_lastStateSize = CGSizeZero;
|
|
354
|
+
_didInitiallyPresent = NO;
|
|
355
|
+
_dismissedByNavigation = NO;
|
|
356
|
+
_pendingNavigationRepresent = NO;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
#pragma mark - Child Component Mounting
|
|
360
|
+
|
|
361
|
+
- (void)cleanupContainerView {
|
|
362
|
+
if (_containerView == nil)
|
|
363
|
+
return;
|
|
364
|
+
|
|
365
|
+
_containerView.delegate = nil;
|
|
366
|
+
[_touchHandler detachFromView:_containerView];
|
|
367
|
+
[_containerView removeFromSuperview];
|
|
368
|
+
|
|
369
|
+
_containerView = nil;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
- (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index {
|
|
373
|
+
if (![childComponentView isKindOfClass:[TrueSheetContainerView class]])
|
|
374
|
+
return;
|
|
375
|
+
|
|
376
|
+
if (_containerView != nil && _containerView != childComponentView) {
|
|
377
|
+
RCTLogWarn(@"TrueSheet: Sheet can only have one container component.");
|
|
378
|
+
[self cleanupContainerView];
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
if (_snapshotView) {
|
|
382
|
+
[_snapshotView removeFromSuperview];
|
|
383
|
+
_snapshotView = nil;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
_containerView = (TrueSheetContainerView *)childComponentView;
|
|
387
|
+
_containerView.delegate = self;
|
|
388
|
+
|
|
389
|
+
[_touchHandler attachToView:_containerView];
|
|
390
|
+
[_controller.view addSubview:_containerView];
|
|
391
|
+
[_controller.view bringSubviewToFront:_containerView];
|
|
392
|
+
_containerView.accessibilityViewIsModal = YES;
|
|
393
|
+
_controller.accessibilityContentView = _containerView;
|
|
394
|
+
[_controller setupAccessibilityContainer];
|
|
395
|
+
|
|
396
|
+
CGFloat contentHeight = [_containerView contentHeight];
|
|
397
|
+
if (contentHeight > 0) {
|
|
398
|
+
_controller.contentHeight = @(contentHeight);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
CGFloat headerHeight = [_containerView headerHeight];
|
|
402
|
+
if (headerHeight > 0) {
|
|
403
|
+
_controller.headerHeight = @(headerHeight);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
CGFloat footerHeight = [_containerView footerHeight];
|
|
407
|
+
if (footerHeight > 0) {
|
|
408
|
+
_controller.footerHeight = @(footerHeight);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
CGFloat peekContentHeight = [_containerView peekContentHeight];
|
|
412
|
+
if (peekContentHeight > 0) {
|
|
413
|
+
_controller.peekContentHeight = @(peekContentHeight);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
if (_eventEmitter) {
|
|
417
|
+
[TrueSheetLifecycleEvents emitMount:_eventEmitter];
|
|
418
|
+
} else {
|
|
419
|
+
_pendingMountEvent = YES;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
- (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index {
|
|
424
|
+
if (![childComponentView isKindOfClass:[TrueSheetContainerView class]])
|
|
425
|
+
return;
|
|
426
|
+
|
|
427
|
+
if (_containerView == nil || _containerView != childComponentView)
|
|
428
|
+
return;
|
|
429
|
+
|
|
430
|
+
if (_controller.isPresented) {
|
|
431
|
+
UIView *superView = _containerView.superview;
|
|
432
|
+
UIView *snapshot = [_containerView snapshotViewAfterScreenUpdates:NO];
|
|
433
|
+
if (snapshot) {
|
|
434
|
+
snapshot.frame = _containerView.frame;
|
|
435
|
+
[superView insertSubview:snapshot belowSubview:_containerView];
|
|
436
|
+
_snapshotView = snapshot;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
[self cleanupContainerView];
|
|
441
|
+
}
|
|
442
|
+
|
|
108
443
|
#pragma mark - TurboModule Methods
|
|
109
444
|
|
|
110
445
|
- (void)presentAtIndex:(NSInteger)index
|
|
111
446
|
animated:(BOOL)animated
|
|
112
447
|
completion:(nullable TrueSheetCompletionBlock)completion {
|
|
113
|
-
if (_controller.isPresented) {
|
|
114
|
-
|
|
115
|
-
[self->_controller setupActiveDetentWithIndex:index];
|
|
116
|
-
}];
|
|
117
|
-
|
|
448
|
+
if (_controller.isBeingPresented || _controller.isPresented) {
|
|
449
|
+
RCTLogWarn(@"TrueSheet: sheet is already presented. Use resize() to change detent.");
|
|
118
450
|
if (completion) {
|
|
119
451
|
completion(YES, nil);
|
|
120
452
|
}
|
|
121
453
|
return;
|
|
122
454
|
}
|
|
123
455
|
|
|
124
|
-
|
|
456
|
+
// Reset navigation dismiss flag when presenting (handles view recycling edge cases)
|
|
457
|
+
_dismissedByNavigation = NO;
|
|
125
458
|
|
|
459
|
+
UIViewController *presentingViewController = [self findPresentingViewController];
|
|
126
460
|
if (!presentingViewController) {
|
|
127
461
|
NSError *error = [NSError errorWithDomain:@"com.lodev09.TrueSheet"
|
|
128
462
|
code:1001
|
|
129
463
|
userInfo:@{NSLocalizedDescriptionKey : @"No presenting view controller found"}];
|
|
130
|
-
|
|
131
464
|
if (completion) {
|
|
132
465
|
completion(NO, error);
|
|
133
466
|
}
|
|
134
467
|
return;
|
|
135
468
|
}
|
|
136
469
|
|
|
137
|
-
|
|
470
|
+
[_controller setupAnchorViewInView:presentingViewController.view];
|
|
471
|
+
[_controller setupSheetSizing];
|
|
138
472
|
[_controller setupSheetProps];
|
|
139
|
-
[_controller setupSheetDetents];
|
|
140
473
|
|
|
141
|
-
//
|
|
474
|
+
// Pin before measuring so a first-time pin doesn't shift sizes mid-animation.
|
|
475
|
+
[self setupScrollable];
|
|
476
|
+
|
|
477
|
+
// Measure synchronously so the presentation starts at the right height —
|
|
478
|
+
// async size reports would otherwise land mid-animation and force a
|
|
479
|
+
// detent retarget that snaps the presentation stack.
|
|
480
|
+
if (_containerView) {
|
|
481
|
+
_controller.contentHeight = @([_containerView contentHeight]);
|
|
482
|
+
_controller.headerHeight = @([_containerView headerHeight]);
|
|
483
|
+
_controller.footerHeight = @([_containerView footerHeight]);
|
|
484
|
+
_controller.peekContentHeight = @([_containerView peekContentHeight]);
|
|
485
|
+
}
|
|
486
|
+
_pendingSizeChange = NO;
|
|
487
|
+
|
|
488
|
+
[_controller setupSheetDetents];
|
|
142
489
|
[_controller setupActiveDetentWithIndex:index];
|
|
143
490
|
|
|
144
|
-
|
|
145
|
-
[
|
|
491
|
+
[_screensEventObserver capturePresenterScreenFromView:self];
|
|
492
|
+
[_screensEventObserver startObservingWithState:_state.get()->getData()];
|
|
493
|
+
|
|
494
|
+
[presentingViewController presentViewController:_controller
|
|
146
495
|
animated:animated
|
|
147
496
|
completion:^{
|
|
148
|
-
// Call completion handler
|
|
149
497
|
if (completion) {
|
|
150
498
|
completion(YES, nil);
|
|
151
499
|
}
|
|
152
500
|
}];
|
|
153
501
|
}
|
|
154
502
|
|
|
155
|
-
- (void)
|
|
503
|
+
- (void)resizeToIndex:(NSInteger)index completion:(nullable TrueSheetCompletionBlock)completion {
|
|
156
504
|
if (!_controller.isPresented) {
|
|
505
|
+
RCTLogWarn(@"TrueSheet: Cannot resize. Sheet is not presented.");
|
|
157
506
|
if (completion) {
|
|
158
507
|
completion(YES, nil);
|
|
159
508
|
}
|
|
160
509
|
return;
|
|
161
510
|
}
|
|
162
511
|
|
|
163
|
-
[_controller
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
completion(YES, nil);
|
|
167
|
-
}
|
|
168
|
-
}];
|
|
169
|
-
}
|
|
512
|
+
[_controller.sheetPresentationController animateChanges:^{
|
|
513
|
+
[self->_controller resizeToDetentIndex:index];
|
|
514
|
+
}];
|
|
170
515
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
[_controller.sheetPresentationController animateChanges:^{
|
|
174
|
-
[self->_controller setupActiveDetentWithIndex:index];
|
|
175
|
-
}];
|
|
516
|
+
if (completion) {
|
|
517
|
+
completion(YES, nil);
|
|
176
518
|
}
|
|
177
519
|
}
|
|
178
520
|
|
|
179
|
-
- (
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
const auto &newProps = *std::static_pointer_cast<TrueSheetViewProps const>(props);
|
|
183
|
-
|
|
184
|
-
// Update detents - pass numbers directly (-1 represents "auto")
|
|
185
|
-
NSMutableArray *detents = [NSMutableArray new];
|
|
186
|
-
for (const auto &detent : newProps.detents) {
|
|
187
|
-
[detents addObject:@(detent)];
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
_controller.detents = detents;
|
|
191
|
-
|
|
192
|
-
// Update background color - always set it, even if 0 (which could be a valid color like black)
|
|
193
|
-
UIColor *color = RCTUIColorFromSharedColor(SharedColor(newProps.background));
|
|
194
|
-
_controller.backgroundColor = color;
|
|
195
|
-
|
|
196
|
-
// Update blur tint - always set it to clear when removed
|
|
197
|
-
_controller.blurTint = !newProps.blurTint.empty() ? RCTNSStringFromString(newProps.blurTint) : nil;
|
|
198
|
-
|
|
199
|
-
// Update corner radius
|
|
200
|
-
if (newProps.cornerRadius < 0) {
|
|
201
|
-
_controller.cornerRadius = nil;
|
|
202
|
-
} else {
|
|
203
|
-
_controller.cornerRadius = @(newProps.cornerRadius);
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// Update max height
|
|
207
|
-
if (newProps.maxHeight != 0.0) {
|
|
208
|
-
_controller.maxHeight = @(newProps.maxHeight);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
// Update grabber
|
|
212
|
-
_controller.grabber = newProps.grabber;
|
|
521
|
+
- (TrueSheetViewController *)viewController {
|
|
522
|
+
return _controller;
|
|
523
|
+
}
|
|
213
524
|
|
|
214
|
-
|
|
215
|
-
|
|
525
|
+
- (void)emitDismissedPosition {
|
|
526
|
+
[TrueSheetStateEvents emitPositionChange:_eventEmitter
|
|
527
|
+
index:-1
|
|
528
|
+
position:_controller.screenHeight
|
|
529
|
+
detent:0
|
|
530
|
+
realtime:NO];
|
|
531
|
+
}
|
|
216
532
|
|
|
217
|
-
|
|
218
|
-
_controller.
|
|
533
|
+
- (void)dismissAnimated:(BOOL)animated completion:(nullable TrueSheetCompletionBlock)completion {
|
|
534
|
+
if (_controller.isBeingDismissed || !_controller.isPresented) {
|
|
535
|
+
RCTLogWarn(@"TrueSheet: sheet is already dismissed. No need to dismiss it again.");
|
|
219
536
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
537
|
+
if (completion) {
|
|
538
|
+
completion(YES, nil);
|
|
539
|
+
}
|
|
540
|
+
return;
|
|
223
541
|
}
|
|
224
542
|
|
|
225
|
-
//
|
|
226
|
-
|
|
227
|
-
|
|
543
|
+
// Dismiss from the presenting view controller to dismiss this sheet and all its children
|
|
544
|
+
UIViewController *presenter = _controller.presentingViewController;
|
|
545
|
+
[presenter dismissViewControllerAnimated:animated
|
|
546
|
+
completion:^{
|
|
547
|
+
if (completion) {
|
|
548
|
+
completion(YES, nil);
|
|
549
|
+
}
|
|
550
|
+
}];
|
|
228
551
|
}
|
|
229
552
|
|
|
230
|
-
- (void)
|
|
231
|
-
|
|
553
|
+
- (void)dismissStackAnimated:(BOOL)animated completion:(nullable TrueSheetCompletionBlock)completion {
|
|
554
|
+
if (_controller.isBeingDismissed || !_controller.isPresented) {
|
|
555
|
+
RCTLogWarn(@"TrueSheet: sheet is already dismissed. No need to dismiss it again.");
|
|
232
556
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
// Apply changes to presented sheet if needed
|
|
236
|
-
if (_controller.isPresented) {
|
|
237
|
-
[_controller.sheetPresentationController animateChanges:^{
|
|
238
|
-
[self->_controller setupSheetDetents];
|
|
239
|
-
[self->_controller applyActiveDetent];
|
|
240
|
-
}];
|
|
241
|
-
} else {
|
|
242
|
-
// Handle initial presentation
|
|
243
|
-
if (_initialDetentIndex >= 0 && !_controller.isPresented) {
|
|
244
|
-
[self presentAtIndex:_initialDetentIndex animated:_initialDetentAnimated completion:nil];
|
|
245
|
-
}
|
|
557
|
+
if (completion) {
|
|
558
|
+
completion(YES, nil);
|
|
246
559
|
}
|
|
560
|
+
return;
|
|
247
561
|
}
|
|
248
|
-
}
|
|
249
562
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
NSLog(@"TrueSheet: Sheet can only have one container component.");
|
|
255
|
-
return;
|
|
563
|
+
// Only dismiss presented children, not this sheet itself
|
|
564
|
+
if (!_controller.presentedViewController) {
|
|
565
|
+
if (completion) {
|
|
566
|
+
completion(YES, nil);
|
|
256
567
|
}
|
|
568
|
+
return;
|
|
569
|
+
}
|
|
257
570
|
|
|
258
|
-
|
|
571
|
+
// Calling dismiss on _controller dismisses all VCs presented on top of it, but keeps _controller presented
|
|
572
|
+
[_controller dismissViewControllerAnimated:animated
|
|
573
|
+
completion:^{
|
|
574
|
+
if (completion) {
|
|
575
|
+
completion(YES, nil);
|
|
576
|
+
}
|
|
577
|
+
}];
|
|
578
|
+
}
|
|
259
579
|
|
|
260
|
-
|
|
261
|
-
_containerView.delegate = self;
|
|
580
|
+
#pragma mark - TrueSheetContainerViewDelegate
|
|
262
581
|
|
|
263
|
-
|
|
264
|
-
|
|
582
|
+
/**
|
|
583
|
+
* Debounced sheet update to handle rapid content/header size changes.
|
|
584
|
+
*/
|
|
585
|
+
- (void)setupSheetDetentsForSizeChange {
|
|
586
|
+
// Retargeting the in-flight presentation makes UIKit snap the whole stack
|
|
587
|
+
// (including the sheet behind) instead of animating. Defer to didPresent —
|
|
588
|
+
// presentAtIndex measured synchronously, so this is usually a no-op.
|
|
589
|
+
if (_controller.isBeingPresented) {
|
|
590
|
+
_pendingSizeChange = YES;
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
265
593
|
|
|
266
|
-
|
|
267
|
-
|
|
594
|
+
// Not presented: presentAtIndex measures at present time.
|
|
595
|
+
// Dismissing: the sheet is going away — touching detents perturbs the
|
|
596
|
+
// presentation stack, visibly glitching the sheet behind.
|
|
597
|
+
if (!_controller.isPresented || _controller.isBeingDismissed)
|
|
598
|
+
return;
|
|
268
599
|
|
|
269
|
-
|
|
270
|
-
|
|
600
|
+
if (_isSheetUpdatePending)
|
|
601
|
+
return;
|
|
271
602
|
|
|
272
|
-
|
|
273
|
-
[_controller.view bringSubviewToFront:_containerView];
|
|
603
|
+
_isSheetUpdatePending = YES;
|
|
274
604
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
if (
|
|
278
|
-
|
|
279
|
-
}
|
|
605
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
606
|
+
self->_isSheetUpdatePending = NO;
|
|
607
|
+
if (!self->_containerView || self->_controller.isBeingDismissed)
|
|
608
|
+
return;
|
|
280
609
|
|
|
281
|
-
//
|
|
282
|
-
|
|
283
|
-
|
|
610
|
+
// Refresh here (not just on peek size events) since the peek's offset
|
|
611
|
+
// within the content can change without its own size changing.
|
|
612
|
+
self->_controller.peekContentHeight = @([self->_containerView peekContentHeight]);
|
|
613
|
+
[self->_controller setupSheetDetentsForSizeChange];
|
|
614
|
+
});
|
|
284
615
|
}
|
|
285
616
|
|
|
286
|
-
- (void)
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
// Detach touch handler
|
|
291
|
-
if (_touchHandler) {
|
|
292
|
-
[_touchHandler detachFromView:_containerView];
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
// Unpin and remove from view hierarchy
|
|
296
|
-
[LayoutUtil unpinView:_containerView];
|
|
297
|
-
[_containerView removeFromSuperview];
|
|
298
|
-
|
|
299
|
-
_containerView = nil;
|
|
300
|
-
}
|
|
617
|
+
- (void)containerViewContentDidChangeSize:(CGSize)newSize {
|
|
618
|
+
_controller.contentHeight = @(newSize.height);
|
|
619
|
+
[self setupSheetDetentsForSizeChange];
|
|
301
620
|
}
|
|
302
621
|
|
|
303
|
-
- (void)
|
|
304
|
-
|
|
305
|
-
[self
|
|
306
|
-
|
|
307
|
-
// Unregister from the registry
|
|
308
|
-
// Note: Re-registration will happen automatically when the component is reused
|
|
309
|
-
[TrueSheetModule unregisterViewWithTag:@(self.tag)];
|
|
622
|
+
- (void)containerViewHeaderDidChangeSize:(CGSize)newSize {
|
|
623
|
+
_controller.headerHeight = @(newSize.height);
|
|
624
|
+
[self setupSheetDetentsForSizeChange];
|
|
310
625
|
}
|
|
311
626
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
CGFloat contentHeight = containerHeight > 0 ? MIN(newSize.height, containerHeight) : newSize.height;
|
|
318
|
-
|
|
319
|
-
_controller.contentHeight = @(contentHeight);
|
|
627
|
+
- (void)containerViewFooterDidChangeSize:(CGSize)newSize {
|
|
628
|
+
_controller.footerHeight = @(newSize.height);
|
|
629
|
+
[self setupSheetDetentsForSizeChange];
|
|
630
|
+
[_controller setupAccessibilityContainer];
|
|
631
|
+
}
|
|
320
632
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
// Controller viewDidLayoutSubviews will handle position notification.
|
|
325
|
-
_controller.layoutTransitioning = YES;
|
|
633
|
+
- (void)containerViewPeekDidChangeSize:(CGSize)newSize {
|
|
634
|
+
[self setupSheetDetentsForSizeChange];
|
|
635
|
+
}
|
|
326
636
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
}
|
|
637
|
+
// When the ScrollView changes (e.g. conditional remount), re-pin the new ScrollView.
|
|
638
|
+
- (void)containerViewScrollViewDidChange {
|
|
639
|
+
[self setupScrollable];
|
|
331
640
|
}
|
|
332
641
|
|
|
333
642
|
#pragma mark - TrueSheetViewControllerDelegate
|
|
334
643
|
|
|
335
|
-
- (void)
|
|
336
|
-
NSInteger index = [_controller currentDetentIndex];
|
|
337
|
-
CGFloat position = _controller.currentPosition;
|
|
338
|
-
|
|
644
|
+
- (void)viewControllerWillPresentAtIndex:(NSInteger)index position:(CGFloat)position detent:(CGFloat)detent {
|
|
339
645
|
_controller.activeDetentIndex = index;
|
|
340
|
-
|
|
341
|
-
[OnWillPresentEvent emit:_eventEmitter index:index position:position];
|
|
342
|
-
|
|
343
|
-
// Emit onChangeSize event to layout our container on JS
|
|
344
|
-
CGSize controllerSize = _controller.view.frame.size;
|
|
345
|
-
[OnSizeChangeEvent emit:_eventEmitter width:controllerSize.width height:controllerSize.height];
|
|
646
|
+
[TrueSheetLifecycleEvents emitWillPresent:_eventEmitter index:index position:position detent:detent];
|
|
346
647
|
}
|
|
347
648
|
|
|
348
|
-
- (void)
|
|
349
|
-
|
|
350
|
-
|
|
649
|
+
- (void)viewControllerDidPresentAtIndex:(NSInteger)index position:(CGFloat)position detent:(CGFloat)detent {
|
|
650
|
+
[_containerView setupKeyboardObserverWithViewController:_controller];
|
|
651
|
+
[TrueSheetLifecycleEvents emitDidPresent:_eventEmitter index:index position:position detent:detent];
|
|
652
|
+
|
|
653
|
+
if (_pendingPropsUpdate) {
|
|
654
|
+
_pendingPropsUpdate = NO;
|
|
655
|
+
[self applySheetPropsUpdate];
|
|
656
|
+
}
|
|
351
657
|
|
|
352
|
-
|
|
658
|
+
if (_pendingSizeChange) {
|
|
659
|
+
_pendingSizeChange = NO;
|
|
660
|
+
[self setupSheetDetentsForSizeChange];
|
|
661
|
+
}
|
|
353
662
|
}
|
|
354
663
|
|
|
355
|
-
- (void)viewControllerDidDrag:(UIGestureRecognizerState)state
|
|
664
|
+
- (void)viewControllerDidDrag:(UIGestureRecognizerState)state
|
|
665
|
+
index:(NSInteger)index
|
|
666
|
+
position:(CGFloat)position
|
|
667
|
+
detent:(CGFloat)detent {
|
|
356
668
|
switch (state) {
|
|
357
669
|
case UIGestureRecognizerStateBegan:
|
|
358
|
-
[
|
|
670
|
+
[TrueSheetDragEvents emitDragBegin:_eventEmitter index:index position:position detent:detent];
|
|
359
671
|
break;
|
|
360
|
-
|
|
361
672
|
case UIGestureRecognizerStateChanged:
|
|
362
|
-
[
|
|
673
|
+
[TrueSheetDragEvents emitDragChange:_eventEmitter index:index position:position detent:detent];
|
|
363
674
|
break;
|
|
364
|
-
|
|
365
675
|
case UIGestureRecognizerStateEnded:
|
|
366
676
|
case UIGestureRecognizerStateCancelled:
|
|
367
|
-
[
|
|
677
|
+
[TrueSheetDragEvents emitDragEnd:_eventEmitter index:index position:position detent:detent];
|
|
368
678
|
break;
|
|
369
|
-
|
|
370
679
|
default:
|
|
371
680
|
break;
|
|
372
681
|
}
|
|
373
682
|
}
|
|
374
683
|
|
|
375
684
|
- (void)viewControllerWillDismiss {
|
|
376
|
-
|
|
685
|
+
if (!_dismissedByNavigation) {
|
|
686
|
+
[TrueSheetLifecycleEvents emitWillDismiss:_eventEmitter];
|
|
687
|
+
}
|
|
377
688
|
}
|
|
378
689
|
|
|
379
690
|
- (void)viewControllerDidDismiss {
|
|
380
|
-
|
|
691
|
+
[_containerView cleanupKeyboardObserver];
|
|
692
|
+
if (!_dismissedByNavigation) {
|
|
693
|
+
_dismissedByNavigation = NO;
|
|
694
|
+
_pendingNavigationRepresent = NO;
|
|
381
695
|
|
|
382
|
-
|
|
696
|
+
_controller.activeDetentIndex = -1;
|
|
697
|
+
[TrueSheetLifecycleEvents emitDidDismiss:_eventEmitter];
|
|
698
|
+
}
|
|
383
699
|
}
|
|
384
700
|
|
|
385
|
-
- (void)viewControllerDidChangeDetent:(NSInteger)index position:(CGFloat)position {
|
|
701
|
+
- (void)viewControllerDidChangeDetent:(NSInteger)index position:(CGFloat)position detent:(CGFloat)detent {
|
|
386
702
|
if (_controller.activeDetentIndex != index) {
|
|
387
703
|
_controller.activeDetentIndex = index;
|
|
388
704
|
}
|
|
389
|
-
|
|
390
|
-
[OnDetentChangeEvent emit:_eventEmitter index:index position:position];
|
|
705
|
+
[TrueSheetStateEvents emitDetentChange:_eventEmitter index:index position:position detent:detent];
|
|
391
706
|
}
|
|
392
707
|
|
|
393
|
-
- (void)viewControllerDidChangePosition:(
|
|
394
|
-
|
|
708
|
+
- (void)viewControllerDidChangePosition:(CGFloat)index
|
|
709
|
+
position:(CGFloat)position
|
|
710
|
+
detent:(CGFloat)detent
|
|
711
|
+
realtime:(BOOL)realtime {
|
|
712
|
+
[TrueSheetStateEvents emitPositionChange:_eventEmitter index:index position:position detent:detent realtime:realtime];
|
|
395
713
|
}
|
|
396
714
|
|
|
397
715
|
- (void)viewControllerDidChangeSize:(CGSize)size {
|
|
398
|
-
[
|
|
716
|
+
[self updateStateWithSize:size];
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
- (void)viewControllerWillFocus {
|
|
720
|
+
[TrueSheetFocusEvents emitWillFocus:_eventEmitter];
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
- (void)viewControllerDidFocus {
|
|
724
|
+
[TrueSheetFocusEvents emitDidFocus:_eventEmitter];
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
- (void)viewControllerWillBlur {
|
|
728
|
+
[TrueSheetFocusEvents emitWillBlur:_eventEmitter];
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
- (void)viewControllerDidBlur {
|
|
732
|
+
[TrueSheetFocusEvents emitDidBlur:_eventEmitter];
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
#pragma mark - RNScreensEventObserverDelegate
|
|
736
|
+
|
|
737
|
+
- (void)presenterScreenWillDisappear {
|
|
738
|
+
if (_controller.isPresented && !_controller.isBeingDismissed) {
|
|
739
|
+
_dismissedByNavigation = YES;
|
|
740
|
+
[self dismissAnimated:YES completion:nil];
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
- (void)presenterScreenWillAppear {
|
|
745
|
+
if (_dismissedByNavigation && !_controller.isPresented && !_controller.isBeingPresented) {
|
|
746
|
+
_dismissedByNavigation = NO;
|
|
747
|
+
|
|
748
|
+
if (self.window) {
|
|
749
|
+
[self presentAtIndex:_controller.activeDetentIndex animated:YES completion:nil];
|
|
750
|
+
} else {
|
|
751
|
+
_pendingNavigationRepresent = YES;
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
- (void)presenterInteractiveDismissDidBegin {
|
|
757
|
+
[_controller beginInteractiveDismiss];
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
- (void)presenterInteractiveDismissDidUpdate:(CGFloat)progress {
|
|
761
|
+
[_controller updateInteractiveDismiss:progress];
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
- (void)presenterInteractiveDismissDidEnd:(BOOL)cancelled duration:(NSTimeInterval)duration {
|
|
765
|
+
if (cancelled) {
|
|
766
|
+
[_controller cancelInteractiveDismissWithDuration:duration];
|
|
767
|
+
return;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
_dismissedByNavigation = YES;
|
|
771
|
+
__weak __typeof(self) weakSelf = self;
|
|
772
|
+
[_controller finishInteractiveDismissWithDuration:duration
|
|
773
|
+
completion:^{
|
|
774
|
+
[weakSelf dismissAnimated:NO completion:nil];
|
|
775
|
+
}];
|
|
399
776
|
}
|
|
400
777
|
|
|
401
778
|
#pragma mark - Private Helpers
|
|
402
779
|
|
|
403
|
-
- (
|
|
404
|
-
|
|
780
|
+
- (void)setupScrollable {
|
|
781
|
+
if (!_containerView)
|
|
782
|
+
return;
|
|
405
783
|
|
|
406
|
-
|
|
407
|
-
|
|
784
|
+
_containerView.insetAdjustment = _insetAdjustment;
|
|
785
|
+
_containerView.scrollableOptions = _scrollableOptions;
|
|
786
|
+
_containerView.hasAutoDetent = _hasAutoDetent;
|
|
787
|
+
_containerView.footerBottomInset = _controller.footerBottomInset;
|
|
788
|
+
[_containerView setupScrollable];
|
|
789
|
+
|
|
790
|
+
// Publish the inset so a footer set later (e.g. navigation setOptions) is
|
|
791
|
+
// padded on its very first layout instead of resizing the sheet twice.
|
|
792
|
+
if (_insetAdjustment == TrueSheetViewInsetAdjustment::Automatic) {
|
|
793
|
+
TrueSheetInsets::setBottomSafeArea(_controller.footerBottomInset);
|
|
408
794
|
}
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
- (void)applySheetPropsUpdate {
|
|
798
|
+
BOOL pendingLayoutUpdate = _pendingLayoutUpdate;
|
|
799
|
+
_pendingLayoutUpdate = NO;
|
|
800
|
+
|
|
801
|
+
if (_pendingDetents) {
|
|
802
|
+
_controller.detents = _pendingDetents;
|
|
803
|
+
_pendingDetents = nil;
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
UIView *presenterView = _controller.presentingViewController.view;
|
|
807
|
+
[_controller setupAnchorViewInView:presenterView];
|
|
808
|
+
|
|
809
|
+
[_controller setupSheetSizing];
|
|
810
|
+
|
|
811
|
+
[_controller.sheetPresentationController animateChanges:^{
|
|
812
|
+
[self->_controller setupSheetProps];
|
|
813
|
+
if (pendingLayoutUpdate) {
|
|
814
|
+
[self->_controller setupSheetDetentsForDetentsChange];
|
|
815
|
+
} else {
|
|
816
|
+
[self->_controller setupSheetDetents];
|
|
817
|
+
}
|
|
818
|
+
[self->_controller applyActiveDetent];
|
|
819
|
+
}];
|
|
820
|
+
[_controller setupDraggable];
|
|
821
|
+
}
|
|
409
822
|
|
|
410
|
-
|
|
823
|
+
- (UIViewController *)findPresentingViewController {
|
|
824
|
+
if (!self.window)
|
|
825
|
+
return nil;
|
|
826
|
+
|
|
827
|
+
UIViewController *rootViewController = self.window.rootViewController;
|
|
828
|
+
if (!rootViewController)
|
|
829
|
+
return nil;
|
|
411
830
|
|
|
412
|
-
// Find
|
|
831
|
+
// Find topmost presented view controller that is not being dismissed
|
|
413
832
|
while (rootViewController.presentedViewController) {
|
|
414
833
|
UIViewController *presented = rootViewController.presentedViewController;
|
|
415
834
|
|
|
416
|
-
// Skip
|
|
417
|
-
if (
|
|
835
|
+
// Skip any view controller that is being dismissed
|
|
836
|
+
if (presented.isBeingDismissed) {
|
|
418
837
|
break;
|
|
419
838
|
}
|
|
420
|
-
|
|
421
839
|
rootViewController = presented;
|
|
422
840
|
}
|
|
423
841
|
|