@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
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
/* Registered so it can transition in sync with `transform` during snaps.
|
|
2
|
+
Descendants derive their visible-height layout from it, so `inherits: true`
|
|
3
|
+
is required. Unsupported browsers ignore this and the value just jumps to
|
|
4
|
+
the snap target instead of animating. */
|
|
5
|
+
@property --snap-point-height {
|
|
6
|
+
syntax: '<length>';
|
|
7
|
+
inherits: true;
|
|
8
|
+
initial-value: 0px;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
[data-vaul-drawer] {
|
|
12
|
+
touch-action: none;
|
|
13
|
+
will-change: transform;
|
|
14
|
+
transition:
|
|
15
|
+
transform 0.5s cubic-bezier(0.32, 0.72, 0, 1),
|
|
16
|
+
--snap-point-height 0.5s cubic-bezier(0.32, 0.72, 0, 1);
|
|
17
|
+
animation-duration: 0.5s;
|
|
18
|
+
animation-timing-function: cubic-bezier(0.32, 0.72, 0, 1);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
[data-vaul-drawer][data-vaul-snap-points='false'][data-vaul-drawer-direction='bottom'][data-state='open'] {
|
|
22
|
+
animation-name: slideFromBottom;
|
|
23
|
+
}
|
|
24
|
+
[data-vaul-drawer][data-vaul-snap-points='false'][data-vaul-drawer-direction='bottom'][data-state='closed'] {
|
|
25
|
+
animation-name: slideToBottom;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/* Drawers always dismiss by sliding the wrapper off-screen, so we don't want
|
|
29
|
+
vaul's default `slideTo*` drawer keyframes (they'd stack with the wrapper
|
|
30
|
+
translate and look twice as fast). Override with a no-op animation of
|
|
31
|
+
matching duration so Radix Presence still waits for it before unmounting.
|
|
32
|
+
Specificity needs to beat the 4-attribute `slideTo*` selectors above. */
|
|
33
|
+
[data-vaul-drawer][data-vaul-drawer-direction='bottom'][data-vaul-animate='true'][data-state='closed'] {
|
|
34
|
+
animation-name: vaulHold;
|
|
35
|
+
animation-duration: 0.5s;
|
|
36
|
+
}
|
|
37
|
+
@keyframes vaulHold {
|
|
38
|
+
from {
|
|
39
|
+
opacity: 1;
|
|
40
|
+
}
|
|
41
|
+
to {
|
|
42
|
+
opacity: 1;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
[data-vaul-drawer][data-vaul-snap-points='false'][data-vaul-drawer-direction='top'][data-state='open'] {
|
|
47
|
+
animation-name: slideFromTop;
|
|
48
|
+
}
|
|
49
|
+
[data-vaul-drawer][data-vaul-snap-points='false'][data-vaul-drawer-direction='top'][data-state='closed'] {
|
|
50
|
+
animation-name: slideToTop;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
[data-vaul-drawer][data-vaul-snap-points='false'][data-vaul-drawer-direction='left'][data-state='open'] {
|
|
54
|
+
animation-name: slideFromLeft;
|
|
55
|
+
}
|
|
56
|
+
[data-vaul-drawer][data-vaul-snap-points='false'][data-vaul-drawer-direction='left'][data-state='closed'] {
|
|
57
|
+
animation-name: slideToLeft;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
[data-vaul-drawer][data-vaul-snap-points='false'][data-vaul-drawer-direction='right'][data-state='open'] {
|
|
61
|
+
animation-name: slideFromRight;
|
|
62
|
+
}
|
|
63
|
+
[data-vaul-drawer][data-vaul-snap-points='false'][data-vaul-drawer-direction='right'][data-state='closed'] {
|
|
64
|
+
animation-name: slideToRight;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
[data-vaul-drawer][data-vaul-snap-points='true'][data-vaul-drawer-direction='bottom'] {
|
|
68
|
+
transform: translate3d(0, var(--initial-transform, 100%), 0);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
[data-vaul-drawer][data-vaul-snap-points='true'][data-vaul-drawer-direction='top'] {
|
|
72
|
+
transform: translate3d(0, calc(var(--initial-transform, 100%) * -1), 0);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
[data-vaul-drawer][data-vaul-snap-points='true'][data-vaul-drawer-direction='left'] {
|
|
76
|
+
transform: translate3d(calc(var(--initial-transform, 100%) * -1), 0, 0);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
[data-vaul-drawer][data-vaul-snap-points='true'][data-vaul-drawer-direction='right'] {
|
|
80
|
+
transform: translate3d(var(--initial-transform, 100%), 0, 0);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
[data-vaul-drawer][data-vaul-delayed-snap-points='true'][data-vaul-drawer-direction='top'] {
|
|
84
|
+
transform: translate3d(0, var(--snap-point-height, 0), 0);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
[data-vaul-drawer][data-vaul-delayed-snap-points='true'][data-vaul-drawer-direction='bottom'] {
|
|
88
|
+
transform: translate3d(0, var(--snap-point-height, 0), 0);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
[data-vaul-drawer][data-vaul-delayed-snap-points='true'][data-vaul-drawer-direction='left'] {
|
|
92
|
+
transform: translate3d(var(--snap-point-height, 0), 0, 0);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
[data-vaul-drawer][data-vaul-delayed-snap-points='true'][data-vaul-drawer-direction='right'] {
|
|
96
|
+
transform: translate3d(var(--snap-point-height, 0), 0, 0);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/* Below the last snap point, vertical touch pans should move the sheet — not
|
|
100
|
+
scroll the content (matches native). touch-action is latched at gesture
|
|
101
|
+
start and ancestors above a scroller aren't consulted, so every descendant
|
|
102
|
+
(nested scrollers included) must opt out of vertical panning ahead of time.
|
|
103
|
+
pan-x keeps horizontal carousels inside the content working. Wheel/trackpad
|
|
104
|
+
scrolling is unaffected. */
|
|
105
|
+
[data-vaul-scroll-locked],
|
|
106
|
+
[data-vaul-scroll-locked] * {
|
|
107
|
+
touch-action: pan-x !important;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
[data-vaul-overlay][data-vaul-snap-points='false'] {
|
|
111
|
+
animation-duration: 0.5s;
|
|
112
|
+
animation-timing-function: cubic-bezier(0.32, 0.72, 0, 1);
|
|
113
|
+
}
|
|
114
|
+
[data-vaul-overlay][data-vaul-snap-points='false'][data-state='open'] {
|
|
115
|
+
animation-name: fadeIn;
|
|
116
|
+
}
|
|
117
|
+
[data-vaul-overlay][data-state='closed'] {
|
|
118
|
+
animation-name: fadeOut;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
[data-vaul-animate='false'] {
|
|
122
|
+
animation: none !important;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
[data-vaul-overlay][data-vaul-snap-points='true'] {
|
|
126
|
+
opacity: 0;
|
|
127
|
+
transition: opacity 0.5s cubic-bezier(0.32, 0.72, 0, 1);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
[data-vaul-drawer]:not([data-vaul-custom-container='true'])::after {
|
|
131
|
+
content: '';
|
|
132
|
+
position: absolute;
|
|
133
|
+
background: inherit;
|
|
134
|
+
background-color: inherit;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
[data-vaul-drawer][data-vaul-drawer-direction='top']::after {
|
|
138
|
+
top: initial;
|
|
139
|
+
bottom: 100%;
|
|
140
|
+
left: 0;
|
|
141
|
+
right: 0;
|
|
142
|
+
height: 200%;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
[data-vaul-drawer][data-vaul-drawer-direction='bottom']::after {
|
|
146
|
+
top: 100%;
|
|
147
|
+
bottom: initial;
|
|
148
|
+
left: 0;
|
|
149
|
+
right: 0;
|
|
150
|
+
height: 200%;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
[data-vaul-drawer][data-vaul-drawer-direction='left']::after {
|
|
154
|
+
left: initial;
|
|
155
|
+
right: 100%;
|
|
156
|
+
top: 0;
|
|
157
|
+
bottom: 0;
|
|
158
|
+
width: 200%;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
[data-vaul-drawer][data-vaul-drawer-direction='right']::after {
|
|
162
|
+
left: 100%;
|
|
163
|
+
right: initial;
|
|
164
|
+
top: 0;
|
|
165
|
+
bottom: 0;
|
|
166
|
+
width: 200%;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
[data-vaul-overlay][data-vaul-snap-points='true'][data-vaul-delayed-snap-points='true'][data-vaul-snap-points-overlay='true'] {
|
|
170
|
+
opacity: 1;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
[data-vaul-handle] {
|
|
174
|
+
display: block;
|
|
175
|
+
position: relative;
|
|
176
|
+
opacity: 0.7;
|
|
177
|
+
background: #e2e2e4;
|
|
178
|
+
margin-left: auto;
|
|
179
|
+
margin-right: auto;
|
|
180
|
+
height: 5px;
|
|
181
|
+
width: 32px;
|
|
182
|
+
border-radius: 1rem;
|
|
183
|
+
touch-action: pan-y;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
[data-vaul-handle]:hover,
|
|
187
|
+
[data-vaul-handle]:active {
|
|
188
|
+
opacity: 1;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
[data-vaul-handle-hitarea] {
|
|
192
|
+
position: absolute;
|
|
193
|
+
left: 50%;
|
|
194
|
+
top: 50%;
|
|
195
|
+
transform: translate(-50%, -50%);
|
|
196
|
+
width: max(100%, 2.75rem); /* 44px */
|
|
197
|
+
height: max(100%, 2.75rem); /* 44px */
|
|
198
|
+
touch-action: inherit;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
@media (hover: hover) and (pointer: fine) {
|
|
202
|
+
[data-vaul-drawer] {
|
|
203
|
+
user-select: none;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
@media (pointer: fine) {
|
|
208
|
+
[data-vaul-handle-hitarea] {
|
|
209
|
+
width: 100%;
|
|
210
|
+
height: 100%;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
@keyframes fadeIn {
|
|
215
|
+
from {
|
|
216
|
+
opacity: 0;
|
|
217
|
+
}
|
|
218
|
+
to {
|
|
219
|
+
opacity: 1;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
@keyframes fadeOut {
|
|
224
|
+
to {
|
|
225
|
+
opacity: 0;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
@keyframes slideFromBottom {
|
|
230
|
+
from {
|
|
231
|
+
transform: translate3d(0, var(--initial-transform, 100%), 0);
|
|
232
|
+
}
|
|
233
|
+
to {
|
|
234
|
+
transform: translate3d(0, 0, 0);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
@keyframes slideToBottom {
|
|
239
|
+
to {
|
|
240
|
+
transform: translate3d(0, var(--initial-transform, 100%), 0);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
@keyframes slideFromTop {
|
|
245
|
+
from {
|
|
246
|
+
transform: translate3d(0, calc(var(--initial-transform, 100%) * -1), 0);
|
|
247
|
+
}
|
|
248
|
+
to {
|
|
249
|
+
transform: translate3d(0, 0, 0);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
@keyframes slideToTop {
|
|
254
|
+
to {
|
|
255
|
+
transform: translate3d(0, calc(var(--initial-transform, 100%) * -1), 0);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
@keyframes slideFromLeft {
|
|
260
|
+
from {
|
|
261
|
+
transform: translate3d(calc(var(--initial-transform, 100%) * -1), 0, 0);
|
|
262
|
+
}
|
|
263
|
+
to {
|
|
264
|
+
transform: translate3d(0, 0, 0);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
@keyframes slideToLeft {
|
|
269
|
+
to {
|
|
270
|
+
transform: translate3d(calc(var(--initial-transform, 100%) * -1), 0, 0);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
@keyframes slideFromRight {
|
|
275
|
+
from {
|
|
276
|
+
transform: translate3d(var(--initial-transform, 100%), 0, 0);
|
|
277
|
+
}
|
|
278
|
+
to {
|
|
279
|
+
transform: translate3d(0, 0, 0);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
@keyframes slideToRight {
|
|
284
|
+
to {
|
|
285
|
+
transform: translate3d(var(--initial-transform, 100%), 0, 0);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
declare module './style.css';
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// This code comes from https://github.com/radix-ui/primitives/tree/main/packages/react/compose-refs
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
|
|
5
|
+
type PossibleRef<T> = React.Ref<T> | undefined;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Set a given ref to a given value
|
|
9
|
+
* This utility takes care of different types of refs: callback refs and RefObject(s)
|
|
10
|
+
*/
|
|
11
|
+
function setRef<T>(ref: PossibleRef<T>, value: T) {
|
|
12
|
+
if (typeof ref === 'function') {
|
|
13
|
+
ref(value);
|
|
14
|
+
} else if (ref !== null && ref !== undefined) {
|
|
15
|
+
(ref as React.MutableRefObject<T>).current = value;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* A utility to compose multiple refs together
|
|
21
|
+
* Accepts callback refs and RefObject(s)
|
|
22
|
+
*/
|
|
23
|
+
function composeRefs<T>(...refs: PossibleRef<T>[]) {
|
|
24
|
+
return (node: T) => refs.forEach((ref) => setRef(ref, node));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* A custom hook that composes multiple refs
|
|
29
|
+
* Accepts callback refs and RefObject(s)
|
|
30
|
+
*/
|
|
31
|
+
function useComposedRefs<T>(...refs: PossibleRef<T>[]) {
|
|
32
|
+
return React.useCallback(composeRefs(...refs), refs);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export { composeRefs, useComposedRefs };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// This code comes from https://github.com/radix-ui/primitives/blob/main/packages/react/use-controllable-state/src/useControllableState.tsx
|
|
2
|
+
|
|
3
|
+
import React from 'react';
|
|
4
|
+
|
|
5
|
+
type UseControllableStateParams<T> = {
|
|
6
|
+
prop?: T | undefined;
|
|
7
|
+
defaultProp?: T | undefined;
|
|
8
|
+
onChange?: (state: T) => void;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
type SetStateFn<T> = (prevState?: T) => T;
|
|
12
|
+
|
|
13
|
+
function useCallbackRef<T extends (...args: any[]) => any>(callback: T | undefined): T {
|
|
14
|
+
const callbackRef = React.useRef(callback);
|
|
15
|
+
|
|
16
|
+
React.useEffect(() => {
|
|
17
|
+
callbackRef.current = callback;
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// https://github.com/facebook/react/issues/19240
|
|
21
|
+
return React.useMemo(() => ((...args) => callbackRef.current?.(...args)) as T, []);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function useUncontrolledState<T>({
|
|
25
|
+
defaultProp,
|
|
26
|
+
onChange,
|
|
27
|
+
}: Omit<UseControllableStateParams<T>, 'prop'>) {
|
|
28
|
+
const uncontrolledState = React.useState<T | undefined>(defaultProp);
|
|
29
|
+
const [value] = uncontrolledState;
|
|
30
|
+
const prevValueRef = React.useRef(value);
|
|
31
|
+
const handleChange = useCallbackRef(onChange);
|
|
32
|
+
|
|
33
|
+
React.useEffect(() => {
|
|
34
|
+
if (prevValueRef.current !== value) {
|
|
35
|
+
handleChange(value as T);
|
|
36
|
+
prevValueRef.current = value;
|
|
37
|
+
}
|
|
38
|
+
}, [value, prevValueRef, handleChange]);
|
|
39
|
+
|
|
40
|
+
return uncontrolledState;
|
|
41
|
+
}
|
|
42
|
+
export function useControllableState<T>({
|
|
43
|
+
prop,
|
|
44
|
+
defaultProp,
|
|
45
|
+
onChange = () => {},
|
|
46
|
+
}: UseControllableStateParams<T>) {
|
|
47
|
+
const [uncontrolledProp, setUncontrolledProp] = useUncontrolledState({ defaultProp, onChange });
|
|
48
|
+
const isControlled = prop !== undefined;
|
|
49
|
+
const value = isControlled ? prop : uncontrolledProp;
|
|
50
|
+
const handleChange = useCallbackRef(onChange);
|
|
51
|
+
|
|
52
|
+
const setValue: React.Dispatch<React.SetStateAction<T | undefined>> = React.useCallback(
|
|
53
|
+
(nextValue) => {
|
|
54
|
+
if (isControlled) {
|
|
55
|
+
const setter = nextValue as SetStateFn<T>;
|
|
56
|
+
const next = typeof nextValue === 'function' ? setter(prop) : nextValue;
|
|
57
|
+
if (next !== prop) handleChange(next as T);
|
|
58
|
+
} else {
|
|
59
|
+
setUncontrolledProp(nextValue);
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
[isControlled, prop, setUncontrolledProp, handleChange]
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
return [value, setValue] as const;
|
|
66
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { isSafari } from './browser';
|
|
3
|
+
|
|
4
|
+
let previousBodyPosition: Record<string, string> | null = null;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* This hook is necessary to prevent buggy behavior on iOS devices (need to test on Android).
|
|
8
|
+
* I won't get into too much detail about what bugs it solves, but so far I've found that setting the body to `position: fixed` is the most reliable way to prevent those bugs.
|
|
9
|
+
* Issues that this hook solves:
|
|
10
|
+
* https://github.com/emilkowalski/vaul/issues/435
|
|
11
|
+
* https://github.com/emilkowalski/vaul/issues/433
|
|
12
|
+
* And more that I discovered, but were just not reported.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
export function usePositionFixed({
|
|
16
|
+
isOpen,
|
|
17
|
+
modal,
|
|
18
|
+
nested,
|
|
19
|
+
hasBeenOpened,
|
|
20
|
+
preventScrollRestoration,
|
|
21
|
+
noBodyStyles,
|
|
22
|
+
}: {
|
|
23
|
+
isOpen: boolean;
|
|
24
|
+
modal: boolean;
|
|
25
|
+
nested: boolean;
|
|
26
|
+
hasBeenOpened: boolean;
|
|
27
|
+
preventScrollRestoration: boolean;
|
|
28
|
+
noBodyStyles: boolean;
|
|
29
|
+
}) {
|
|
30
|
+
const [activeUrl, setActiveUrl] = React.useState(() =>
|
|
31
|
+
typeof window !== 'undefined' ? window.location.href : ''
|
|
32
|
+
);
|
|
33
|
+
const scrollPos = React.useRef(0);
|
|
34
|
+
|
|
35
|
+
const setPositionFixed = React.useCallback(() => {
|
|
36
|
+
// All browsers on iOS will return true here.
|
|
37
|
+
if (!isSafari()) return;
|
|
38
|
+
|
|
39
|
+
// If previousBodyPosition is already set, don't set it again.
|
|
40
|
+
if (previousBodyPosition === null && isOpen && !noBodyStyles) {
|
|
41
|
+
previousBodyPosition = {
|
|
42
|
+
position: document.body.style.position,
|
|
43
|
+
top: document.body.style.top,
|
|
44
|
+
left: document.body.style.left,
|
|
45
|
+
height: document.body.style.height,
|
|
46
|
+
right: 'unset',
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// Update the dom inside an animation frame
|
|
50
|
+
const { scrollX, innerHeight } = window;
|
|
51
|
+
|
|
52
|
+
document.body.style.setProperty('position', 'fixed', 'important');
|
|
53
|
+
Object.assign(document.body.style, {
|
|
54
|
+
top: `${-scrollPos.current}px`,
|
|
55
|
+
left: `${-scrollX}px`,
|
|
56
|
+
right: '0px',
|
|
57
|
+
height: 'auto',
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
window.setTimeout(
|
|
61
|
+
() =>
|
|
62
|
+
window.requestAnimationFrame(() => {
|
|
63
|
+
// Attempt to check if the bottom bar appeared due to the position change
|
|
64
|
+
const bottomBarHeight = innerHeight - window.innerHeight;
|
|
65
|
+
if (bottomBarHeight && scrollPos.current >= innerHeight) {
|
|
66
|
+
// Move the content further up so that the bottom bar doesn't hide it
|
|
67
|
+
document.body.style.top = `${-(scrollPos.current + bottomBarHeight)}px`;
|
|
68
|
+
}
|
|
69
|
+
}),
|
|
70
|
+
300
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
}, [isOpen]);
|
|
74
|
+
|
|
75
|
+
const restorePositionSetting = React.useCallback(() => {
|
|
76
|
+
// All browsers on iOS will return true here.
|
|
77
|
+
if (!isSafari()) return;
|
|
78
|
+
|
|
79
|
+
if (previousBodyPosition !== null && !noBodyStyles) {
|
|
80
|
+
// Convert the position from "px" to Int
|
|
81
|
+
const y = -parseInt(document.body.style.top, 10);
|
|
82
|
+
const x = -parseInt(document.body.style.left, 10);
|
|
83
|
+
|
|
84
|
+
// Restore styles
|
|
85
|
+
Object.assign(document.body.style, previousBodyPosition);
|
|
86
|
+
|
|
87
|
+
window.requestAnimationFrame(() => {
|
|
88
|
+
if (preventScrollRestoration && activeUrl !== window.location.href) {
|
|
89
|
+
setActiveUrl(window.location.href);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
window.scrollTo(x, y);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
previousBodyPosition = null;
|
|
97
|
+
}
|
|
98
|
+
}, [activeUrl]);
|
|
99
|
+
|
|
100
|
+
React.useEffect(() => {
|
|
101
|
+
function onScroll() {
|
|
102
|
+
scrollPos.current = window.scrollY;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
onScroll();
|
|
106
|
+
|
|
107
|
+
window.addEventListener('scroll', onScroll);
|
|
108
|
+
|
|
109
|
+
return () => {
|
|
110
|
+
window.removeEventListener('scroll', onScroll);
|
|
111
|
+
};
|
|
112
|
+
}, []);
|
|
113
|
+
|
|
114
|
+
React.useEffect(() => {
|
|
115
|
+
if (!modal) return;
|
|
116
|
+
|
|
117
|
+
return () => {
|
|
118
|
+
if (typeof document === 'undefined') return;
|
|
119
|
+
|
|
120
|
+
// Another drawer is opened, safe to ignore the execution
|
|
121
|
+
const hasDrawerOpened = !!document.querySelector('[data-vaul-drawer]');
|
|
122
|
+
if (hasDrawerOpened) return;
|
|
123
|
+
|
|
124
|
+
restorePositionSetting();
|
|
125
|
+
};
|
|
126
|
+
}, [modal, restorePositionSetting]);
|
|
127
|
+
|
|
128
|
+
React.useEffect(() => {
|
|
129
|
+
if (nested || !hasBeenOpened) return;
|
|
130
|
+
// This is needed to force Safari toolbar to show **before** the drawer starts animating to prevent a gnarly shift from happening
|
|
131
|
+
if (isOpen) {
|
|
132
|
+
// avoid for standalone mode (PWA)
|
|
133
|
+
const isStandalone = window.matchMedia('(display-mode: standalone)').matches;
|
|
134
|
+
!isStandalone && setPositionFixed();
|
|
135
|
+
|
|
136
|
+
if (!modal) {
|
|
137
|
+
window.setTimeout(() => {
|
|
138
|
+
restorePositionSetting();
|
|
139
|
+
}, 500);
|
|
140
|
+
}
|
|
141
|
+
} else {
|
|
142
|
+
restorePositionSetting();
|
|
143
|
+
}
|
|
144
|
+
}, [isOpen, hasBeenOpened, activeUrl, modal, nested, setPositionFixed, restorePositionSetting]);
|
|
145
|
+
|
|
146
|
+
return { restorePositionSetting };
|
|
147
|
+
}
|