@lodev09/react-native-true-sheet 4.0.0-beta.0 → 4.0.0-beta.2
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 +156 -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 +1224 -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/TouchEventDeduper.kt +31 -0
- 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 +1133 -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 +230 -64
- package/lib/module/TrueSheet.js.map +1 -1
- package/lib/module/TrueSheet.web.js +1203 -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 +95 -0
- package/lib/module/mocks/navigation.js.map +1 -0
- package/lib/module/mocks/navigationExpoRouter.js +21 -0
- package/lib/module/mocks/navigationExpoRouter.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/TrueSheetNavigatorContent.js +73 -0
- package/lib/module/navigation/TrueSheetNavigatorContent.js.map +1 -0
- package/lib/module/navigation/actions.js +50 -0
- package/lib/module/navigation/actions.js.map +1 -0
- package/lib/module/navigation/createTrueSheetRouter.js +166 -0
- package/lib/module/navigation/createTrueSheetRouter.js.map +1 -0
- package/lib/module/navigation/expo-router/index.js +48 -0
- package/lib/module/navigation/expo-router/index.js.map +1 -0
- package/lib/module/navigation/index.js +47 -0
- package/lib/module/navigation/index.js.map +1 -0
- package/lib/module/navigation/navigator.js +10 -0
- package/lib/module/navigation/navigator.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/dom.js +10 -0
- package/lib/module/web/dom.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 +99 -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 +70 -0
- package/lib/typescript/src/mocks/navigation.d.ts.map +1 -0
- package/lib/typescript/src/mocks/navigationExpoRouter.d.ts +22 -0
- package/lib/typescript/src/mocks/navigationExpoRouter.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/TrueSheetNavigatorContent.d.ts +5 -0
- package/lib/typescript/src/navigation/TrueSheetNavigatorContent.d.ts.map +1 -0
- package/lib/typescript/src/navigation/actions.d.ts +71 -0
- package/lib/typescript/src/navigation/actions.d.ts.map +1 -0
- package/lib/typescript/src/navigation/createTrueSheetRouter.d.ts +14 -0
- package/lib/typescript/src/navigation/createTrueSheetRouter.d.ts.map +1 -0
- package/lib/typescript/src/navigation/expo-router/index.d.ts +37 -0
- package/lib/typescript/src/navigation/expo-router/index.d.ts.map +1 -0
- package/lib/typescript/src/navigation/index.d.ts +46 -0
- package/lib/typescript/src/navigation/index.d.ts.map +1 -0
- package/lib/typescript/src/navigation/navigator.d.ts +7 -0
- package/lib/typescript/src/navigation/navigator.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 +14 -0
- package/lib/typescript/src/navigation/screen/types.d.ts.map +1 -0
- package/lib/typescript/src/navigation/screen/useSheetScreenState.d.ts +33 -0
- package/lib/typescript/src/navigation/screen/useSheetScreenState.d.ts.map +1 -0
- package/lib/typescript/src/navigation/types.d.ts +177 -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/dom.d.ts +7 -0
- package/lib/typescript/src/web/dom.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 +95 -36
- package/react-native.config.js +9 -2
- package/src/TrueSheet.tsx +281 -62
- package/src/TrueSheet.types.ts +525 -71
- package/src/TrueSheet.web.tsx +1362 -0
- package/src/TrueSheetPeek.tsx +11 -0
- package/src/TrueSheetPeek.web.tsx +64 -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 +79 -0
- package/src/mocks/navigationExpoRouter.ts +40 -0
- package/src/mocks/reanimated.ts +100 -0
- package/src/navigation/TrueSheetNavigatorContent.tsx +106 -0
- package/src/navigation/actions.ts +78 -0
- package/src/navigation/createTrueSheetRouter.ts +222 -0
- package/src/navigation/expo-router/index.ts +89 -0
- package/src/navigation/index.ts +81 -0
- package/src/navigation/navigator.ts +18 -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 +19 -0
- package/src/navigation/screen/useSheetScreenState.ts +100 -0
- package/src/navigation/types.ts +251 -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/dom.ts +9 -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 +131 -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
|
@@ -10,18 +10,32 @@
|
|
|
10
10
|
|
|
11
11
|
#import "TrueSheetContentView.h"
|
|
12
12
|
#import <React/RCTScrollViewComponentView.h>
|
|
13
|
-
#import <react/renderer/components/TrueSheetSpec/ComponentDescriptors.h>
|
|
14
13
|
#import <react/renderer/components/TrueSheetSpec/EventEmitters.h>
|
|
15
14
|
#import <react/renderer/components/TrueSheetSpec/Props.h>
|
|
16
15
|
#import <react/renderer/components/TrueSheetSpec/RCTComponentViewHelpers.h>
|
|
16
|
+
#import <react/renderer/components/TrueSheetSpec/TrueSheetContentViewComponentDescriptor.h>
|
|
17
|
+
#import <react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.h>
|
|
18
|
+
#import "TrueSheetContainerView.h"
|
|
19
|
+
#import "TrueSheetFooterView.h"
|
|
20
|
+
#import "TrueSheetView.h"
|
|
17
21
|
#import "TrueSheetViewController.h"
|
|
18
|
-
#import "utils/
|
|
22
|
+
#import "utils/PlatformUtil.h"
|
|
23
|
+
#import "utils/UIView+FirstResponder.h"
|
|
19
24
|
|
|
20
25
|
using namespace facebook::react;
|
|
21
26
|
|
|
27
|
+
static void *TrueSheetContentSizeContext = &TrueSheetContentSizeContext;
|
|
28
|
+
|
|
22
29
|
@implementation TrueSheetContentView {
|
|
30
|
+
TrueSheetContentViewShadowNode::ConcreteState::Shared _state;
|
|
23
31
|
RCTScrollViewComponentView *_pinnedScrollView;
|
|
32
|
+
UIScrollView *_observedScrollView;
|
|
24
33
|
CGSize _lastSize;
|
|
34
|
+
CGFloat _bottomInset;
|
|
35
|
+
CGFloat _originalIndicatorBottomInset;
|
|
36
|
+
BOOL _observingTextChanges;
|
|
37
|
+
BOOL _scrollableBounded;
|
|
38
|
+
BOOL _isReportPending;
|
|
25
39
|
}
|
|
26
40
|
|
|
27
41
|
+ (ComponentDescriptorProvider)componentDescriptorProvider {
|
|
@@ -32,83 +46,439 @@ using namespace facebook::react;
|
|
|
32
46
|
if (self = [super initWithFrame:frame]) {
|
|
33
47
|
static const auto defaultProps = std::make_shared<const TrueSheetContentViewProps>();
|
|
34
48
|
_props = defaultProps;
|
|
35
|
-
|
|
36
|
-
_pinnedScrollView = nil;
|
|
37
|
-
_lastSize = CGSizeZero;
|
|
38
49
|
}
|
|
39
50
|
return self;
|
|
40
51
|
}
|
|
41
52
|
|
|
53
|
+
- (void)dealloc {
|
|
54
|
+
[self stopObservingTextChanges];
|
|
55
|
+
[self unobserveScrollViewContentSize];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
- (void)updateState:(const State::Shared &)state oldState:(const State::Shared &)oldState {
|
|
59
|
+
_state = std::static_pointer_cast<TrueSheetContentViewShadowNode::ConcreteState const>(state);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Tells the shadow node to fill the container (flexGrow/flexShrink) so the
|
|
63
|
+
// pinned ScrollView's viewport is bounded to the visible space. Only applied
|
|
64
|
+
// for auto detents — otherwise content lays out naturally like a regular view.
|
|
65
|
+
- (void)setScrollableBounded:(BOOL)bounded {
|
|
66
|
+
if (_scrollableBounded == bounded) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
_scrollableBounded = bounded;
|
|
70
|
+
|
|
71
|
+
if (_state) {
|
|
72
|
+
TrueSheetContentViewState newState;
|
|
73
|
+
newState.scrollableBounded = bounded;
|
|
74
|
+
_state->updateState(std::move(newState));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
- (void)setHasAutoDetent:(BOOL)hasAutoDetent {
|
|
79
|
+
if (_hasAutoDetent == hasAutoDetent) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
_hasAutoDetent = hasAutoDetent;
|
|
83
|
+
|
|
84
|
+
if (_pinnedScrollView) {
|
|
85
|
+
[self setScrollableBounded:hasAutoDetent];
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
#pragma mark - Text Change Observing
|
|
90
|
+
|
|
91
|
+
// The notification is app-wide (object:nil), so only observe while the keyboard is up
|
|
92
|
+
- (void)startObservingTextChanges {
|
|
93
|
+
if (_observingTextChanges) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
_observingTextChanges = YES;
|
|
97
|
+
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
98
|
+
selector:@selector(focusedInputTextDidChange:)
|
|
99
|
+
name:UITextViewTextDidChangeNotification
|
|
100
|
+
object:nil];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
- (void)stopObservingTextChanges {
|
|
104
|
+
if (!_observingTextChanges) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
_observingTextChanges = NO;
|
|
108
|
+
[[NSNotificationCenter defaultCenter] removeObserver:self name:UITextViewTextDidChangeNotification object:nil];
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
#pragma mark - Layout
|
|
112
|
+
|
|
113
|
+
- (CGFloat)naturalHeight {
|
|
114
|
+
CGFloat height = self.frame.size.height;
|
|
115
|
+
if (_pinnedScrollView) {
|
|
116
|
+
height += _pinnedScrollView.scrollView.contentSize.height - _pinnedScrollView.frame.size.height;
|
|
117
|
+
}
|
|
118
|
+
return MAX(0, height);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
- (void)reportSizeIfChanged {
|
|
122
|
+
// A deep ScrollView unmount doesn't pass through this view's mount hooks —
|
|
123
|
+
// detect the stale pin here so it (and its contentSize observation) is
|
|
124
|
+
// released instead of lingering until the next explicit setup or recycle.
|
|
125
|
+
if (_pinnedScrollView && ![_pinnedScrollView isDescendantOfView:self]) {
|
|
126
|
+
[self.delegate contentViewScrollViewDidChange];
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// naturalHeight mixes frames from different views; mid-transaction they're
|
|
130
|
+
// momentarily inconsistent (parent updates before the ScrollView), which
|
|
131
|
+
// feeds back into the auto detent and oscillates. Coalesce to the next
|
|
132
|
+
// main-queue tick so frames are settled before measuring.
|
|
133
|
+
if (_pinnedScrollView) {
|
|
134
|
+
if (_isReportPending) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
_isReportPending = YES;
|
|
138
|
+
|
|
139
|
+
__weak __typeof(self) weakSelf = self;
|
|
140
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
141
|
+
__typeof(self) strongSelf = weakSelf;
|
|
142
|
+
if (!strongSelf) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
strongSelf->_isReportPending = NO;
|
|
146
|
+
[strongSelf reportSizeNow];
|
|
147
|
+
});
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
[self reportSizeNow];
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
- (void)reportSizeNow {
|
|
155
|
+
CGSize newSize = CGSizeMake(self.frame.size.width, self.naturalHeight);
|
|
156
|
+
if (!CGSizeEqualToSize(newSize, _lastSize)) {
|
|
157
|
+
_lastSize = newSize;
|
|
158
|
+
[self.delegate contentViewDidChangeSize:newSize];
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
42
162
|
- (void)updateLayoutMetrics:(const LayoutMetrics &)layoutMetrics
|
|
43
163
|
oldLayoutMetrics:(const LayoutMetrics &)oldLayoutMetrics {
|
|
44
164
|
[super updateLayoutMetrics:layoutMetrics oldLayoutMetrics:oldLayoutMetrics];
|
|
165
|
+
[self reportSizeIfChanged];
|
|
166
|
+
}
|
|
45
167
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
168
|
+
#pragma mark - Child Mounting
|
|
169
|
+
|
|
170
|
+
- (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index {
|
|
171
|
+
[super mountChildComponentView:childComponentView index:index];
|
|
172
|
+
[self checkScrollViewChanged];
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
- (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index {
|
|
176
|
+
[super unmountChildComponentView:childComponentView index:index];
|
|
177
|
+
[self checkScrollViewChanged];
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
- (void)checkScrollViewChanged {
|
|
181
|
+
if (!_pinnedScrollView || ![_pinnedScrollView isDescendantOfView:self]) {
|
|
182
|
+
[self.delegate contentViewScrollViewDidChange];
|
|
53
183
|
}
|
|
54
184
|
}
|
|
55
185
|
|
|
56
|
-
-
|
|
57
|
-
|
|
186
|
+
#pragma mark - Scrollable
|
|
187
|
+
|
|
188
|
+
- (void)setScrollViewContentInset:(CGFloat)contentBottom indicatorInset:(CGFloat)indicatorBottom {
|
|
189
|
+
if (!_pinnedScrollView)
|
|
190
|
+
return;
|
|
191
|
+
|
|
192
|
+
UIEdgeInsets contentInset = _pinnedScrollView.scrollView.contentInset;
|
|
193
|
+
contentInset.bottom = contentBottom;
|
|
194
|
+
_pinnedScrollView.scrollView.contentInset = contentInset;
|
|
195
|
+
|
|
196
|
+
UIEdgeInsets indicatorInsets = _pinnedScrollView.scrollView.verticalScrollIndicatorInsets;
|
|
197
|
+
indicatorInsets.bottom = indicatorBottom;
|
|
198
|
+
_pinnedScrollView.scrollView.verticalScrollIndicatorInsets = indicatorInsets;
|
|
199
|
+
}
|
|
58
200
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
[self setupScrollViewPinning];
|
|
201
|
+
- (void)clearScrollable {
|
|
202
|
+
if (_pinnedScrollView) {
|
|
203
|
+
[self setScrollViewContentInset:0 indicatorInset:_originalIndicatorBottomInset];
|
|
63
204
|
}
|
|
205
|
+
[self unobserveScrollViewContentSize];
|
|
206
|
+
[self setScrollableBounded:NO];
|
|
207
|
+
_pinnedScrollView = nil;
|
|
208
|
+
_bottomInset = 0;
|
|
209
|
+
_originalIndicatorBottomInset = 0;
|
|
210
|
+
[self reportSizeIfChanged];
|
|
64
211
|
}
|
|
65
212
|
|
|
66
|
-
- (void)
|
|
67
|
-
//
|
|
68
|
-
|
|
213
|
+
- (void)setupScrollableWithBottomInset:(CGFloat)bottomInset {
|
|
214
|
+
// Check if pinned scroll view is still valid (still in view hierarchy)
|
|
215
|
+
if (_pinnedScrollView && ![_pinnedScrollView isDescendantOfView:self]) {
|
|
216
|
+
[self clearScrollable];
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Already set up with same inset and valid scroll view
|
|
220
|
+
if (_pinnedScrollView && _bottomInset == bottomInset) {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
|
|
69
224
|
RCTScrollViewComponentView *scrollView = [self findScrollView];
|
|
225
|
+
if (!scrollView) {
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
70
228
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
229
|
+
// Only capture originals on first pin
|
|
230
|
+
if (!_pinnedScrollView) {
|
|
231
|
+
_originalIndicatorBottomInset = scrollView.scrollView.verticalScrollIndicatorInsets.bottom;
|
|
232
|
+
_pinnedScrollView = scrollView;
|
|
76
233
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
234
|
+
[self observeScrollViewContentSize];
|
|
235
|
+
[self setScrollableBounded:_hasAutoDetent];
|
|
236
|
+
[self reportSizeIfChanged];
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
_bottomInset = bottomInset;
|
|
240
|
+
|
|
241
|
+
[self setScrollViewContentInset:_bottomInset indicatorInset:_originalIndicatorBottomInset];
|
|
242
|
+
|
|
243
|
+
// If keyboard is currently showing, re-apply the keyboard inset to the new ScrollView
|
|
244
|
+
CGFloat keyboardHeight = _keyboardObserver ? _keyboardObserver.currentHeight : 0;
|
|
245
|
+
if (keyboardHeight > 0) {
|
|
246
|
+
CGFloat inset = [self keyboardInsetWithHeight:keyboardHeight];
|
|
247
|
+
[self setScrollViewContentInset:inset indicatorInset:_originalIndicatorBottomInset + inset];
|
|
83
248
|
}
|
|
84
249
|
}
|
|
85
250
|
|
|
251
|
+
// An absolute footer rises above the keyboard and covers the content's bottom
|
|
252
|
+
// edge — include it so the caret clears the footer, not just the keyboard.
|
|
253
|
+
// A relative footer stays behind the keyboard below the content, so its
|
|
254
|
+
// height shields that much of the keyboard's overlap.
|
|
255
|
+
- (CGFloat)keyboardInsetWithHeight:(CGFloat)height {
|
|
256
|
+
if (!self.footerView) {
|
|
257
|
+
return height;
|
|
258
|
+
}
|
|
259
|
+
if (_keyboardObserver.viewController.absoluteFooter) {
|
|
260
|
+
return height + [self.footerView keyboardOcclusionHeight];
|
|
261
|
+
}
|
|
262
|
+
return MAX(0, height - self.footerView.frame.size.height);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Content growth is invisible to layout once the viewport is bounded, so track
|
|
266
|
+
// the scroll content size directly to keep the auto detent height in sync.
|
|
267
|
+
- (void)observeScrollViewContentSize {
|
|
268
|
+
UIScrollView *scrollView = _pinnedScrollView.scrollView;
|
|
269
|
+
if (_observedScrollView == scrollView) {
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
[self unobserveScrollViewContentSize];
|
|
273
|
+
_observedScrollView = scrollView;
|
|
274
|
+
[scrollView addObserver:self
|
|
275
|
+
forKeyPath:@"contentSize"
|
|
276
|
+
options:NSKeyValueObservingOptionNew
|
|
277
|
+
context:TrueSheetContentSizeContext];
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
- (void)unobserveScrollViewContentSize {
|
|
281
|
+
if (_observedScrollView) {
|
|
282
|
+
[_observedScrollView removeObserver:self forKeyPath:@"contentSize" context:TrueSheetContentSizeContext];
|
|
283
|
+
_observedScrollView = nil;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
- (void)observeValueForKeyPath:(NSString *)keyPath
|
|
288
|
+
ofObject:(id)object
|
|
289
|
+
change:(NSDictionary *)change
|
|
290
|
+
context:(void *)context {
|
|
291
|
+
if (context == TrueSheetContentSizeContext) {
|
|
292
|
+
[self reportSizeIfChanged];
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
|
|
296
|
+
}
|
|
297
|
+
|
|
86
298
|
- (RCTScrollViewComponentView *)findScrollView {
|
|
87
|
-
|
|
299
|
+
if (_pinnedScrollView) {
|
|
300
|
+
return _pinnedScrollView;
|
|
301
|
+
}
|
|
302
|
+
|
|
88
303
|
if (self.subviews.count == 0) {
|
|
89
304
|
return nil;
|
|
90
305
|
}
|
|
91
306
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
307
|
+
RCTScrollViewComponentView *scrollView = [self findScrollViewInSubviews:self.subviews];
|
|
308
|
+
|
|
309
|
+
if (!scrollView) {
|
|
310
|
+
for (UIView *subview in self.subviews) {
|
|
311
|
+
scrollView = [self findScrollViewInSubviews:subview.subviews];
|
|
312
|
+
if (scrollView) {
|
|
313
|
+
break;
|
|
314
|
+
}
|
|
96
315
|
}
|
|
97
316
|
}
|
|
98
317
|
|
|
318
|
+
return scrollView;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
- (RCTScrollViewComponentView *)findScrollViewInSubviews:(NSArray<UIView *> *)subviews {
|
|
322
|
+
for (UIView *subview in subviews) {
|
|
323
|
+
if ([subview isKindOfClass:RCTScrollViewComponentView.class] && ![subview isKindOfClass:TrueSheetView.class]) {
|
|
324
|
+
return (RCTScrollViewComponentView *)subview;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
99
327
|
return nil;
|
|
100
328
|
}
|
|
101
329
|
|
|
102
|
-
-
|
|
103
|
-
[super prepareForRecycle];
|
|
330
|
+
#pragma mark - Scroll Edge Effects
|
|
104
331
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
332
|
+
- (void)applyScrollEdgeEffects:(nullable ScrollableOptions *)options {
|
|
333
|
+
#if RNTS_IPHONE_OS_VERSION_AVAILABLE(26_0)
|
|
334
|
+
if (!_pinnedScrollView)
|
|
335
|
+
return;
|
|
336
|
+
|
|
337
|
+
if (@available(iOS 26.0, *)) {
|
|
338
|
+
UIScrollView *scrollView = _pinnedScrollView.scrollView;
|
|
339
|
+
auto topEffect = options ? options.topScrollEdgeEffect : TrueSheetViewTopScrollEdgeEffect::Hidden;
|
|
340
|
+
auto bottomEffect = options ? options.bottomScrollEdgeEffect : TrueSheetViewBottomScrollEdgeEffect::Hidden;
|
|
341
|
+
|
|
342
|
+
[self applyEdgeEffect:topEffect toEdge:scrollView.topEdgeEffect];
|
|
343
|
+
[self applyEdgeEffect:(TrueSheetViewTopScrollEdgeEffect)bottomEffect toEdge:scrollView.bottomEdgeEffect];
|
|
344
|
+
}
|
|
345
|
+
#endif
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
#if RNTS_IPHONE_OS_VERSION_AVAILABLE(26_0)
|
|
349
|
+
- (void)applyEdgeEffect:(TrueSheetViewTopScrollEdgeEffect)effect
|
|
350
|
+
toEdge:(UIScrollEdgeEffect *)edgeEffect API_AVAILABLE(ios(26.0)) {
|
|
351
|
+
switch (effect) {
|
|
352
|
+
case TrueSheetViewTopScrollEdgeEffect::Automatic:
|
|
353
|
+
edgeEffect.hidden = NO;
|
|
354
|
+
edgeEffect.style = UIScrollEdgeEffectStyle.automaticStyle;
|
|
355
|
+
break;
|
|
356
|
+
case TrueSheetViewTopScrollEdgeEffect::Hard:
|
|
357
|
+
edgeEffect.hidden = NO;
|
|
358
|
+
edgeEffect.style = UIScrollEdgeEffectStyle.hardStyle;
|
|
359
|
+
break;
|
|
360
|
+
case TrueSheetViewTopScrollEdgeEffect::Soft:
|
|
361
|
+
edgeEffect.hidden = NO;
|
|
362
|
+
edgeEffect.style = UIScrollEdgeEffectStyle.softStyle;
|
|
363
|
+
break;
|
|
364
|
+
case TrueSheetViewTopScrollEdgeEffect::Hidden:
|
|
365
|
+
edgeEffect.hidden = YES;
|
|
366
|
+
break;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
#endif
|
|
370
|
+
|
|
371
|
+
#pragma mark - TrueSheetKeyboardObserverDelegate
|
|
372
|
+
|
|
373
|
+
- (void)keyboardWillShow:(CGFloat)height duration:(NSTimeInterval)duration curve:(UIViewAnimationOptions)curve {
|
|
374
|
+
if (!_pinnedScrollView) {
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
[self startObservingTextChanges];
|
|
379
|
+
|
|
380
|
+
TrueSheetViewController *sheetController = _keyboardObserver.viewController;
|
|
381
|
+
UIView *firstResponder = sheetController ? [sheetController.view findFirstResponder] : nil;
|
|
382
|
+
|
|
383
|
+
CGFloat inset = [self keyboardInsetWithHeight:height];
|
|
384
|
+
[UIView animateWithDuration:duration
|
|
385
|
+
delay:0
|
|
386
|
+
options:curve | UIViewAnimationOptionBeginFromCurrentState
|
|
387
|
+
animations:^{
|
|
388
|
+
[self setScrollViewContentInset:inset indicatorInset:self->_originalIndicatorBottomInset + inset];
|
|
389
|
+
}
|
|
390
|
+
completion:nil];
|
|
391
|
+
|
|
392
|
+
// Defer scroll until the next run loop so content insets are applied first
|
|
393
|
+
if (firstResponder) {
|
|
394
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
395
|
+
[self scrollToFocusedCaretAnimated:YES];
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
- (void)focusedInputTextDidChange:(NSNotification *)notification {
|
|
401
|
+
if (!_pinnedScrollView || !_keyboardObserver || _keyboardObserver.currentHeight <= 0) {
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
TrueSheetViewController *sheetController = _keyboardObserver.viewController;
|
|
406
|
+
UIView *firstResponder = sheetController ? [sheetController.view findFirstResponder] : nil;
|
|
407
|
+
if (!firstResponder || notification.object != firstResponder) {
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
412
|
+
[self scrollToFocusedCaretAnimated:YES];
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
- (void)scrollToFocusedCaretAnimated:(BOOL)animated {
|
|
417
|
+
if (!_pinnedScrollView) {
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
TrueSheetViewController *sheetController = _keyboardObserver.viewController;
|
|
422
|
+
UIView *firstResponder = sheetController ? [sheetController.view findFirstResponder] : nil;
|
|
423
|
+
if (!firstResponder) {
|
|
424
|
+
return;
|
|
109
425
|
}
|
|
426
|
+
|
|
427
|
+
UIScrollView *scrollView = _pinnedScrollView.scrollView;
|
|
428
|
+
CGRect targetRect = [firstResponder convertRect:firstResponder.bounds toView:scrollView];
|
|
429
|
+
|
|
430
|
+
if ([firstResponder conformsToProtocol:@protocol(UITextInput)]) {
|
|
431
|
+
id<UITextInput> textInput = (id<UITextInput>)firstResponder;
|
|
432
|
+
UITextRange *selectedRange = textInput.selectedTextRange;
|
|
433
|
+
if (selectedRange) {
|
|
434
|
+
CGRect caretRect = [textInput caretRectForPosition:selectedRange.end];
|
|
435
|
+
// caretRectForPosition: can return non-finite coordinates during layout/selection transitions
|
|
436
|
+
BOOL caretRectValid = !CGRectIsNull(caretRect) && !CGRectIsInfinite(caretRect) && isfinite(caretRect.origin.x) &&
|
|
437
|
+
isfinite(caretRect.origin.y) && isfinite(caretRect.size.width) &&
|
|
438
|
+
isfinite(caretRect.size.height);
|
|
439
|
+
if (caretRectValid) {
|
|
440
|
+
targetRect = [firstResponder convertRect:caretRect toView:scrollView];
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
targetRect.size.height += self.keyboardScrollOffset;
|
|
446
|
+
[scrollView scrollRectToVisible:targetRect animated:animated];
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
- (void)keyboardWillHide:(NSTimeInterval)duration curve:(UIViewAnimationOptions)curve {
|
|
450
|
+
[self stopObservingTextChanges];
|
|
451
|
+
|
|
452
|
+
if (!_pinnedScrollView) {
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
[UIView animateWithDuration:duration
|
|
457
|
+
delay:0
|
|
458
|
+
options:curve | UIViewAnimationOptionBeginFromCurrentState
|
|
459
|
+
animations:^{
|
|
460
|
+
[self setScrollViewContentInset:self->_bottomInset
|
|
461
|
+
indicatorInset:self->_originalIndicatorBottomInset];
|
|
462
|
+
}
|
|
463
|
+
completion:nil];
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
#pragma mark - Lifecycle
|
|
467
|
+
|
|
468
|
+
- (void)prepareForRecycle {
|
|
469
|
+
[super prepareForRecycle];
|
|
470
|
+
[self stopObservingTextChanges];
|
|
471
|
+
[self clearScrollable];
|
|
472
|
+
_state.reset();
|
|
473
|
+
_scrollableBounded = NO;
|
|
474
|
+
_hasAutoDetent = NO;
|
|
475
|
+
_lastSize = CGSizeZero;
|
|
110
476
|
}
|
|
111
477
|
|
|
112
478
|
@end
|
|
113
479
|
|
|
480
|
+
Class<RCTComponentViewProtocol> TrueSheetContentViewCls(void) {
|
|
481
|
+
return TrueSheetContentView.class;
|
|
482
|
+
}
|
|
483
|
+
|
|
114
484
|
#endif
|
|
@@ -11,14 +11,39 @@
|
|
|
11
11
|
#import <React/RCTSurfaceTouchHandler.h>
|
|
12
12
|
#import <React/RCTViewComponentView.h>
|
|
13
13
|
#import <UIKit/UIKit.h>
|
|
14
|
+
#import "core/TrueSheetKeyboardObserver.h"
|
|
14
15
|
|
|
15
16
|
@class TrueSheetViewController;
|
|
16
17
|
|
|
17
18
|
NS_ASSUME_NONNULL_BEGIN
|
|
18
19
|
|
|
19
|
-
@
|
|
20
|
+
@protocol TrueSheetFooterViewDelegate <NSObject>
|
|
21
|
+
@optional
|
|
22
|
+
- (void)footerViewDidChangeSize:(CGSize)size;
|
|
23
|
+
@end
|
|
24
|
+
|
|
25
|
+
@interface TrueSheetFooterView : RCTViewComponentView <TrueSheetKeyboardObserverDelegate>
|
|
26
|
+
|
|
27
|
+
@property (nonatomic, weak, nullable) TrueSheetKeyboardObserver *keyboardObserver;
|
|
28
|
+
@property (nonatomic, weak, nullable) id<TrueSheetFooterViewDelegate> delegate;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Re-applies the footer's keyboard slide using the current keyboard height.
|
|
32
|
+
* No-op when the keyboard is hidden. Used to reflect live `keyboardOffset` changes.
|
|
33
|
+
*/
|
|
34
|
+
- (void)applyKeyboardOffset;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Bottom safe-area inset the footer absorbs as padding (via the shadow node)
|
|
38
|
+
* so its content clears the home indicator and the background fills the inset.
|
|
39
|
+
*/
|
|
40
|
+
- (void)setBottomInset:(CGFloat)bottomInset;
|
|
20
41
|
|
|
21
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Height the footer occupies above the keyboard — its layout height minus
|
|
44
|
+
* the safe-area inset it drops while the keyboard is open.
|
|
45
|
+
*/
|
|
46
|
+
- (CGFloat)keyboardOcclusionHeight;
|
|
22
47
|
|
|
23
48
|
@end
|
|
24
49
|
|