@lodev09/react-native-true-sheet 4.0.0-beta.1 → 4.0.0-beta.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -4
- package/android/build.gradle +22 -1
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContainerView.kt +24 -7
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentView.kt +211 -182
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentViewManager.kt +5 -1
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetFooterView.kt +14 -19
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetOverlayView.kt +106 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetOverlayViewManager.kt +45 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetPackage.kt +2 -1
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetStateUpdater.kt +18 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +82 -39
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewController.kt +275 -88
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt +26 -1
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetCoordinatorLayout.kt +75 -3
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetDetentCalculator.kt +56 -34
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetOverlayRootView.kt +137 -0
- package/android/src/main/java/com/lodev09/truesheet/events/TrueSheetLifecycleEvents.kt +15 -0
- package/android/src/main/java/com/lodev09/truesheet/utils/KeyboardUtils.kt +1 -1
- package/android/src/main/java/com/lodev09/truesheet/utils/TouchEventDeduper.kt +31 -0
- package/android/src/main/java/com/lodev09/truesheet/utils/ViewUtils.kt +19 -7
- package/android/src/main/jni/TrueSheetSpec.h +1 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewComponentDescriptor.h +0 -8
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.cpp +52 -29
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.h +6 -1
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewState.cpp +1 -1
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewState.h +6 -4
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.cpp +7 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetLayoutUtils.h +46 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewComponentDescriptor.h +21 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewShadowNode.cpp +17 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewShadowNode.h +36 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewShadowNode.cpp +4 -35
- package/ios/TrueSheetContainerView.h +14 -7
- package/ios/TrueSheetContainerView.mm +10 -7
- package/ios/TrueSheetContentView.h +31 -15
- package/ios/TrueSheetContentView.mm +148 -188
- package/ios/TrueSheetFooterView.h +6 -0
- package/ios/TrueSheetFooterView.mm +48 -2
- package/ios/TrueSheetModule.h +2 -7
- package/ios/TrueSheetModule.mm +7 -16
- package/ios/TrueSheetOverlayView.h +32 -0
- package/ios/TrueSheetOverlayView.mm +161 -0
- package/ios/TrueSheetView.mm +171 -29
- package/ios/TrueSheetViewController.h +10 -0
- package/ios/TrueSheetViewController.mm +256 -74
- package/ios/core/TrueSheetGrabberView.mm +13 -3
- package/ios/core/TrueSheetOverlayContainerView.h +31 -0
- package/ios/core/TrueSheetOverlayContainerView.mm +35 -0
- package/ios/events/TrueSheetLifecycleEvents.h +2 -0
- package/ios/events/TrueSheetLifecycleEvents.mm +8 -0
- package/ios/tvos/TrueSheetStubs.mm +12 -0
- package/ios/utils/UIView+ScrollEdgeInteraction.h +1 -0
- package/ios/utils/UIView+ScrollEdgeInteraction.mm +24 -2
- package/lib/module/TrueSheet.js +149 -34
- package/lib/module/TrueSheet.js.map +1 -1
- package/lib/module/TrueSheet.web.js +122 -53
- package/lib/module/TrueSheet.web.js.map +1 -1
- package/lib/module/TrueSheetOverlay.js +30 -0
- package/lib/module/TrueSheetOverlay.js.map +1 -0
- package/lib/module/TrueSheetOverlay.web.js +35 -0
- package/lib/module/TrueSheetOverlay.web.js.map +1 -0
- package/lib/module/TrueSheetPeek.web.js +3 -3
- package/lib/module/TrueSheetPeek.web.js.map +1 -1
- package/lib/module/fabric/TrueSheetContentViewNativeComponent.ts +1 -1
- package/lib/module/fabric/TrueSheetOverlayViewNativeComponent.ts +12 -0
- package/lib/module/fabric/TrueSheetViewNativeComponent.ts +5 -0
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/mocks/index.js +10 -0
- package/lib/module/mocks/index.js.map +1 -1
- package/lib/module/mocks/navigation.js +31 -21
- package/lib/module/mocks/navigation.js.map +1 -1
- package/lib/module/mocks/navigationExpoRouter.js +21 -0
- package/lib/module/mocks/navigationExpoRouter.js.map +1 -0
- package/lib/module/mocks/reanimated.js +1 -1
- package/lib/module/mocks/reanimated.js.map +1 -1
- package/lib/module/navigation/{TrueSheetView.js → TrueSheetNavigatorContent.js} +14 -12
- 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/base-types.js +2 -0
- package/lib/module/navigation/base-types.js.map +1 -0
- package/lib/module/navigation/{TrueSheetRouter.js → createTrueSheetRouter.js} +11 -24
- package/lib/module/navigation/createTrueSheetRouter.js.map +1 -0
- package/lib/module/navigation/expo-router/base-types.js +2 -0
- package/lib/module/navigation/expo-router/base-types.js.map +1 -0
- package/lib/module/navigation/expo-router/index.js +50 -0
- package/lib/module/navigation/expo-router/index.js.map +1 -0
- package/lib/module/navigation/expo-router/types.js +4 -0
- package/lib/module/navigation/expo-router/types.js.map +1 -0
- package/lib/module/navigation/index.js +43 -2
- package/lib/module/navigation/index.js.map +1 -1
- package/lib/module/navigation/navigator.js +10 -0
- package/lib/module/navigation/navigator.js.map +1 -0
- package/lib/module/navigation/screen/ReanimatedTrueSheetScreen.js +2 -2
- package/lib/module/navigation/screen/ReanimatedTrueSheetScreen.js.map +1 -1
- package/lib/module/navigation/screen/TrueSheetScreen.js +2 -2
- package/lib/module/navigation/screen/TrueSheetScreen.js.map +1 -1
- package/lib/module/navigation/screen/useSheetScreenState.js +5 -4
- package/lib/module/navigation/screen/useSheetScreenState.js.map +1 -1
- package/lib/module/navigation/useTrueSheetNavigation.js +1 -1
- package/lib/module/navigation/useTrueSheetNavigation.js.map +1 -1
- package/lib/module/web/dom.js +10 -0
- package/lib/module/web/dom.js.map +1 -0
- package/lib/module/web/vaul/constants.js +4 -0
- package/lib/module/web/vaul/constants.js.map +1 -1
- package/lib/module/web/vaul/context.js.map +1 -1
- package/lib/module/web/vaul/helpers.js +10 -4
- package/lib/module/web/vaul/helpers.js.map +1 -1
- package/lib/module/web/vaul/index.js +35 -2
- package/lib/module/web/vaul/index.js.map +1 -1
- package/lib/typescript/src/TrueSheet.d.ts +6 -0
- package/lib/typescript/src/TrueSheet.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheet.types.d.ts +72 -1
- package/lib/typescript/src/TrueSheet.types.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheet.web.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheetOverlay.d.ts +8 -0
- package/lib/typescript/src/TrueSheetOverlay.d.ts.map +1 -0
- package/lib/typescript/src/TrueSheetOverlay.web.d.ts +8 -0
- package/lib/typescript/src/TrueSheetOverlay.web.d.ts.map +1 -0
- package/lib/typescript/src/TrueSheetPeek.web.d.ts.map +1 -1
- package/lib/typescript/src/fabric/TrueSheetOverlayViewNativeComponent.d.ts +6 -0
- package/lib/typescript/src/fabric/TrueSheetOverlayViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts +4 -0
- package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/mocks/index.d.ts +4 -0
- package/lib/typescript/src/mocks/index.d.ts.map +1 -1
- package/lib/typescript/src/mocks/navigation.d.ts +5 -1
- package/lib/typescript/src/mocks/navigation.d.ts.map +1 -1
- 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.map +1 -1
- 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/base-types.d.ts +9 -0
- package/lib/typescript/src/navigation/base-types.d.ts.map +1 -0
- package/lib/typescript/src/navigation/createTrueSheetRouter.d.ts +3 -0
- package/lib/typescript/src/navigation/createTrueSheetRouter.d.ts.map +1 -0
- package/lib/typescript/src/navigation/expo-router/base-types.d.ts +8 -0
- package/lib/typescript/src/navigation/expo-router/base-types.d.ts.map +1 -0
- package/lib/typescript/src/navigation/expo-router/index.d.ts +37 -0
- package/lib/typescript/src/navigation/expo-router/index.d.ts.map +1 -0
- package/lib/typescript/src/navigation/expo-router/types.d.ts +44 -0
- package/lib/typescript/src/navigation/expo-router/types.d.ts.map +1 -0
- package/lib/typescript/src/navigation/index.d.ts +42 -3
- package/lib/typescript/src/navigation/index.d.ts.map +1 -1
- 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 +1 -1
- package/lib/typescript/src/navigation/screen/ReanimatedTrueSheetScreen.d.ts.map +1 -1
- package/lib/typescript/src/navigation/screen/TrueSheetScreen.d.ts +1 -1
- package/lib/typescript/src/navigation/screen/TrueSheetScreen.d.ts.map +1 -1
- package/lib/typescript/src/navigation/screen/types.d.ts +3 -4
- package/lib/typescript/src/navigation/screen/types.d.ts.map +1 -1
- package/lib/typescript/src/navigation/screen/useSheetScreenState.d.ts +5 -6
- package/lib/typescript/src/navigation/screen/useSheetScreenState.d.ts.map +1 -1
- package/lib/typescript/src/navigation/types.d.ts +65 -5
- package/lib/typescript/src/navigation/types.d.ts.map +1 -1
- package/lib/typescript/src/navigation/useTrueSheetNavigation.d.ts +1 -1
- package/lib/typescript/src/navigation/useTrueSheetNavigation.d.ts.map +1 -1
- 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/constants.d.ts +1 -0
- package/lib/typescript/src/web/vaul/constants.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/context.d.ts +1 -0
- package/lib/typescript/src/web/vaul/context.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/helpers.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/index.d.ts +7 -1
- package/lib/typescript/src/web/vaul/index.d.ts.map +1 -1
- package/package.json +32 -9
- package/react-native.config.js +1 -0
- package/src/TrueSheet.tsx +184 -46
- package/src/TrueSheet.types.ts +77 -1
- package/src/TrueSheet.web.tsx +135 -64
- package/src/TrueSheetOverlay.tsx +24 -0
- package/src/TrueSheetOverlay.web.tsx +33 -0
- package/src/TrueSheetPeek.web.tsx +4 -3
- package/src/fabric/TrueSheetContentViewNativeComponent.ts +1 -1
- package/src/fabric/TrueSheetOverlayViewNativeComponent.ts +12 -0
- package/src/fabric/TrueSheetViewNativeComponent.ts +5 -0
- package/src/index.ts +1 -0
- package/src/mocks/index.ts +7 -0
- package/src/mocks/navigation.ts +32 -25
- package/src/mocks/navigationExpoRouter.ts +41 -0
- package/src/mocks/reanimated.ts +8 -9
- package/src/navigation/{TrueSheetView.tsx → TrueSheetNavigatorContent.tsx} +24 -17
- package/src/navigation/actions.ts +78 -0
- package/src/navigation/base-types.ts +20 -0
- package/src/navigation/createTrueSheetRouter.ts +194 -0
- package/src/navigation/expo-router/base-types.ts +18 -0
- package/src/navigation/expo-router/index.ts +90 -0
- package/src/navigation/expo-router/types.ts +116 -0
- package/src/navigation/index.ts +68 -2
- package/src/navigation/navigator.ts +18 -0
- package/src/navigation/screen/ReanimatedTrueSheetScreen.tsx +2 -2
- package/src/navigation/screen/TrueSheetScreen.tsx +2 -2
- package/src/navigation/screen/types.ts +4 -6
- package/src/navigation/screen/useSheetScreenState.ts +10 -15
- package/src/navigation/types.ts +99 -16
- package/src/navigation/useTrueSheetNavigation.ts +1 -1
- package/src/web/dom.ts +9 -0
- package/src/web/vaul/constants.ts +4 -0
- package/src/web/vaul/context.ts +1 -0
- package/src/web/vaul/helpers.ts +13 -6
- package/src/web/vaul/index.tsx +46 -1
- package/lib/module/navigation/TrueSheetRouter.js.map +0 -1
- package/lib/module/navigation/TrueSheetView.js.map +0 -1
- package/lib/module/navigation/createTrueSheetNavigator.js +0 -63
- package/lib/module/navigation/createTrueSheetNavigator.js.map +0 -1
- package/lib/typescript/src/navigation/TrueSheetRouter.d.ts +0 -57
- package/lib/typescript/src/navigation/TrueSheetRouter.d.ts.map +0 -1
- package/lib/typescript/src/navigation/TrueSheetView.d.ts +0 -10
- package/lib/typescript/src/navigation/TrueSheetView.d.ts.map +0 -1
- package/lib/typescript/src/navigation/createTrueSheetNavigator.d.ts +0 -35
- package/lib/typescript/src/navigation/createTrueSheetNavigator.d.ts.map +0 -1
- package/src/navigation/TrueSheetRouter.ts +0 -234
- package/src/navigation/createTrueSheetNavigator.tsx +0 -93
package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.cpp
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
#include "TrueSheetContentViewShadowNode.h"
|
|
2
2
|
|
|
3
|
+
#include <limits>
|
|
4
|
+
|
|
3
5
|
#include <react/renderer/components/view/conversions.h>
|
|
6
|
+
#include <react/renderer/core/LayoutConstraints.h>
|
|
7
|
+
#include <react/renderer/core/LayoutContext.h>
|
|
4
8
|
|
|
5
9
|
namespace facebook::react {
|
|
6
10
|
|
|
@@ -8,35 +12,54 @@ using namespace yoga;
|
|
|
8
12
|
|
|
9
13
|
extern const char TrueSheetContentViewComponentName[] = "TrueSheetContentView";
|
|
10
14
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
15
|
+
// measure() lays out a clone of this node, which re-enters layout() on the
|
|
16
|
+
// clone — guard so the measurement pass doesn't measure again recursively.
|
|
17
|
+
static thread_local bool gIsMeasuringNaturalHeight = false;
|
|
18
|
+
|
|
19
|
+
void TrueSheetContentViewShadowNode::layout(LayoutContext layoutContext) {
|
|
20
|
+
ConcreteViewShadowNode::layout(layoutContext);
|
|
21
|
+
updateNaturalHeightIfNeeded(layoutContext);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Even auto-height content can be constrained by the container when a
|
|
25
|
+
// descendant ScrollView shrinks to fit. Its committed height then hides
|
|
26
|
+
// content growth, so only a fixed, non-flexible height can be used directly.
|
|
27
|
+
static bool isHeightContainerDerived(const yoga::Style &style) {
|
|
28
|
+
return style.flexGrow().unwrapOrDefault(0) > 0 ||
|
|
29
|
+
style.flexShrink().unwrapOrDefault(0) > 0 ||
|
|
30
|
+
!style.dimension(Dimension::Height).isPoints();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// The natural height is the height the content wants when unbounded — the
|
|
34
|
+
// source for the auto detent. When the content's height derives from the
|
|
35
|
+
// container, the committed layout doesn't reflect it — lay out a clone of the
|
|
36
|
+
// subtree with an unconstrained height instead. Yoga respects the user's
|
|
37
|
+
// styles: an explicit-height ScrollView keeps its height while a flexible one
|
|
38
|
+
// expands to its content — no ScrollView discovery involved.
|
|
39
|
+
void TrueSheetContentViewShadowNode::updateNaturalHeightIfNeeded(
|
|
40
|
+
const LayoutContext &layoutContext) {
|
|
41
|
+
if (gIsMeasuringNaturalHeight) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
auto stateData = getStateData();
|
|
46
|
+
auto size = getLayoutMetrics().frame.size;
|
|
47
|
+
|
|
48
|
+
Float naturalHeight = size.height;
|
|
49
|
+
if (isHeightContainerDerived(getConcreteProps().yogaStyle)) {
|
|
50
|
+
auto constraints = LayoutConstraints{};
|
|
51
|
+
constraints.minimumSize = {size.width, 0};
|
|
52
|
+
constraints.maximumSize = {size.width, std::numeric_limits<Float>::infinity()};
|
|
53
|
+
constraints.layoutDirection = getLayoutMetrics().layoutDirection;
|
|
54
|
+
|
|
55
|
+
gIsMeasuringNaturalHeight = true;
|
|
56
|
+
naturalHeight = measure(layoutContext, constraints).height;
|
|
57
|
+
gIsMeasuringNaturalHeight = false;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (stateData.naturalHeight != naturalHeight) {
|
|
61
|
+
stateData.naturalHeight = naturalHeight;
|
|
62
|
+
setStateData(std::move(stateData));
|
|
40
63
|
}
|
|
41
64
|
}
|
|
42
65
|
|
|
@@ -22,7 +22,12 @@ class JSI_EXPORT TrueSheetContentViewShadowNode final
|
|
|
22
22
|
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
|
23
23
|
|
|
24
24
|
public:
|
|
25
|
-
|
|
25
|
+
#pragma mark - LayoutableShadowNode
|
|
26
|
+
|
|
27
|
+
void layout(LayoutContext layoutContext) override;
|
|
28
|
+
|
|
29
|
+
private:
|
|
30
|
+
void updateNaturalHeightIfNeeded(const LayoutContext &layoutContext);
|
|
26
31
|
};
|
|
27
32
|
|
|
28
33
|
} // namespace facebook::react
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
+
#include <react/renderer/graphics/Float.h>
|
|
4
|
+
|
|
3
5
|
#ifdef ANDROID
|
|
4
6
|
#include <folly/dynamic.h>
|
|
5
7
|
#include <react/renderer/mapbuffer/MapBuffer.h>
|
|
@@ -10,8 +12,8 @@ namespace facebook::react {
|
|
|
10
12
|
|
|
11
13
|
/*
|
|
12
14
|
* State for <TrueSheetContentView> component.
|
|
13
|
-
*
|
|
14
|
-
* content
|
|
15
|
+
* `naturalHeight` is measured by the shadow node during layout — the height
|
|
16
|
+
* the content wants when unbounded (see TrueSheetContentViewShadowNode).
|
|
15
17
|
*/
|
|
16
18
|
class TrueSheetContentViewState final {
|
|
17
19
|
public:
|
|
@@ -21,10 +23,10 @@ class TrueSheetContentViewState final {
|
|
|
21
23
|
TrueSheetContentViewState(
|
|
22
24
|
TrueSheetContentViewState const &previousState,
|
|
23
25
|
folly::dynamic data)
|
|
24
|
-
:
|
|
26
|
+
: naturalHeight(previousState.naturalHeight) {}
|
|
25
27
|
#endif
|
|
26
28
|
|
|
27
|
-
|
|
29
|
+
Float naturalHeight{0};
|
|
28
30
|
|
|
29
31
|
#ifdef ANDROID
|
|
30
32
|
folly::dynamic getDynamic() const;
|
package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.cpp
CHANGED
|
@@ -25,6 +25,13 @@ void TrueSheetFooterViewShadowNode::adjustLayoutWithState() {
|
|
|
25
25
|
float bottomInset = stateData.bottomInset;
|
|
26
26
|
if (!stateData.initialized && props.autoBottomInset) {
|
|
27
27
|
bottomInset = TrueSheetInsets::bottomSafeArea();
|
|
28
|
+
if (bottomInset != stateData.bottomInset) {
|
|
29
|
+
// Record the seeded value so the mounted view reads exactly the inset
|
|
30
|
+
// baked into this layout — the global may change before mount.
|
|
31
|
+
auto seededData = stateData;
|
|
32
|
+
seededData.bottomInset = bottomInset;
|
|
33
|
+
setStateData(std::move(seededData));
|
|
34
|
+
}
|
|
28
35
|
}
|
|
29
36
|
|
|
30
37
|
// A footer pinned to the sheet's bottom edge owns the bottom safe-area
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <react/renderer/components/view/conversions.h>
|
|
4
|
+
#include <yoga/node/Node.h>
|
|
5
|
+
#include <yoga/style/Style.h>
|
|
6
|
+
|
|
7
|
+
namespace facebook::react {
|
|
8
|
+
|
|
9
|
+
/*
|
|
10
|
+
* Overrides a node's Yoga dimensions with the container size reported from
|
|
11
|
+
* native. A zero dimension leaves that axis to Yoga.
|
|
12
|
+
*/
|
|
13
|
+
inline void applyContainerSizeToYogaNode(
|
|
14
|
+
yoga::Node &node,
|
|
15
|
+
const yoga::Style &baseStyle,
|
|
16
|
+
float containerWidth,
|
|
17
|
+
float containerHeight) {
|
|
18
|
+
if (containerWidth <= 0 && containerHeight <= 0) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
yoga::Style adjustedStyle = baseStyle;
|
|
23
|
+
const auto ¤tStyle = node.style();
|
|
24
|
+
bool needsUpdate = false;
|
|
25
|
+
|
|
26
|
+
if (containerWidth > 0) {
|
|
27
|
+
adjustedStyle.setDimension(yoga::Dimension::Width, yoga::StyleSizeLength::points(containerWidth));
|
|
28
|
+
if (adjustedStyle.dimension(yoga::Dimension::Width) != currentStyle.dimension(yoga::Dimension::Width)) {
|
|
29
|
+
needsUpdate = true;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (containerHeight > 0) {
|
|
34
|
+
adjustedStyle.setDimension(yoga::Dimension::Height, yoga::StyleSizeLength::points(containerHeight));
|
|
35
|
+
if (adjustedStyle.dimension(yoga::Dimension::Height) != currentStyle.dimension(yoga::Dimension::Height)) {
|
|
36
|
+
needsUpdate = true;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (needsUpdate) {
|
|
41
|
+
node.setStyle(adjustedStyle);
|
|
42
|
+
node.setDirty(true);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
} // namespace facebook::react
|
package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewComponentDescriptor.h
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewShadowNode.h>
|
|
4
|
+
#include <react/renderer/core/ConcreteComponentDescriptor.h>
|
|
5
|
+
|
|
6
|
+
namespace facebook::react {
|
|
7
|
+
|
|
8
|
+
/*
|
|
9
|
+
* Descriptor for <TrueSheetOverlayView> component.
|
|
10
|
+
*/
|
|
11
|
+
class TrueSheetOverlayViewComponentDescriptor final
|
|
12
|
+
: public ConcreteComponentDescriptor<TrueSheetOverlayViewShadowNode> {
|
|
13
|
+
using ConcreteComponentDescriptor::ConcreteComponentDescriptor;
|
|
14
|
+
|
|
15
|
+
void adopt(ShadowNode &shadowNode) const override {
|
|
16
|
+
static_cast<TrueSheetOverlayViewShadowNode &>(shadowNode).adjustLayoutWithState();
|
|
17
|
+
ConcreteComponentDescriptor::adopt(shadowNode);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
} // namespace facebook::react
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#include "TrueSheetOverlayViewShadowNode.h"
|
|
2
|
+
|
|
3
|
+
#include "TrueSheetLayoutUtils.h"
|
|
4
|
+
|
|
5
|
+
namespace facebook::react {
|
|
6
|
+
|
|
7
|
+
extern const char TrueSheetOverlayViewComponentName[] = "TrueSheetOverlayView";
|
|
8
|
+
|
|
9
|
+
void TrueSheetOverlayViewShadowNode::adjustLayoutWithState() {
|
|
10
|
+
ensureUnsealed();
|
|
11
|
+
|
|
12
|
+
const auto &stateData = getStateData();
|
|
13
|
+
applyContainerSizeToYogaNode(
|
|
14
|
+
yogaNode_, getConcreteProps().yogaStyle, stateData.containerWidth, stateData.containerHeight);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
} // namespace facebook::react
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <jsi/jsi.h>
|
|
4
|
+
#include <react/renderer/components/TrueSheetSpec/EventEmitters.h>
|
|
5
|
+
#include <react/renderer/components/TrueSheetSpec/Props.h>
|
|
6
|
+
#include <react/renderer/components/TrueSheetSpec/TrueSheetViewState.h>
|
|
7
|
+
#include <react/renderer/components/view/ConcreteViewShadowNode.h>
|
|
8
|
+
|
|
9
|
+
namespace facebook::react {
|
|
10
|
+
|
|
11
|
+
JSI_EXPORT extern const char TrueSheetOverlayViewComponentName[];
|
|
12
|
+
|
|
13
|
+
/*
|
|
14
|
+
* `ShadowNode` for <TrueSheetOverlayView> component.
|
|
15
|
+
* Sized to the window from native (via TrueSheetViewState) so its children
|
|
16
|
+
* lay out against the full window like the sheet's container.
|
|
17
|
+
*/
|
|
18
|
+
class JSI_EXPORT TrueSheetOverlayViewShadowNode final
|
|
19
|
+
: public ConcreteViewShadowNode<
|
|
20
|
+
TrueSheetOverlayViewComponentName,
|
|
21
|
+
TrueSheetOverlayViewProps,
|
|
22
|
+
TrueSheetOverlayViewEventEmitter,
|
|
23
|
+
TrueSheetViewState> {
|
|
24
|
+
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
|
25
|
+
|
|
26
|
+
public:
|
|
27
|
+
static ShadowNodeTraits BaseTraits() {
|
|
28
|
+
auto traits = ConcreteViewShadowNode::BaseTraits();
|
|
29
|
+
traits.set(ShadowNodeTraits::Trait::RootNodeKind);
|
|
30
|
+
return traits;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
void adjustLayoutWithState();
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
} // namespace facebook::react
|
|
@@ -1,48 +1,17 @@
|
|
|
1
1
|
#include "TrueSheetViewShadowNode.h"
|
|
2
2
|
|
|
3
|
-
#include
|
|
3
|
+
#include "TrueSheetLayoutUtils.h"
|
|
4
4
|
|
|
5
5
|
namespace facebook::react {
|
|
6
6
|
|
|
7
|
-
using namespace yoga;
|
|
8
|
-
|
|
9
7
|
extern const char TrueSheetViewComponentName[] = "TrueSheetView";
|
|
10
8
|
|
|
11
9
|
void TrueSheetViewShadowNode::adjustLayoutWithState() {
|
|
12
10
|
ensureUnsealed();
|
|
13
11
|
|
|
14
|
-
auto
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
// If container dimensions are set from native, override Yoga's dimensions
|
|
19
|
-
if (stateData.containerWidth > 0 || stateData.containerHeight > 0) {
|
|
20
|
-
auto &props = getConcreteProps();
|
|
21
|
-
yoga::Style adjustedStyle = props.yogaStyle;
|
|
22
|
-
auto currentStyle = yogaNode_.style();
|
|
23
|
-
bool needsUpdate = false;
|
|
24
|
-
|
|
25
|
-
// Set width if provided
|
|
26
|
-
if (stateData.containerWidth > 0) {
|
|
27
|
-
adjustedStyle.setDimension(yoga::Dimension::Width, StyleSizeLength::points(stateData.containerWidth));
|
|
28
|
-
if (adjustedStyle.dimension(yoga::Dimension::Width) != currentStyle.dimension(yoga::Dimension::Width)) {
|
|
29
|
-
needsUpdate = true;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Set height if provided
|
|
34
|
-
if (stateData.containerHeight > 0) {
|
|
35
|
-
adjustedStyle.setDimension(yoga::Dimension::Height, StyleSizeLength::points(stateData.containerHeight));
|
|
36
|
-
if (adjustedStyle.dimension(yoga::Dimension::Height) != currentStyle.dimension(yoga::Dimension::Height)) {
|
|
37
|
-
needsUpdate = true;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (needsUpdate) {
|
|
42
|
-
yogaNode_.setStyle(adjustedStyle);
|
|
43
|
-
yogaNode_.setDirty(true);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
12
|
+
const auto &stateData = getStateData();
|
|
13
|
+
applyContainerSizeToYogaNode(
|
|
14
|
+
yogaNode_, getConcreteProps().yogaStyle, stateData.containerWidth, stateData.containerHeight);
|
|
46
15
|
}
|
|
47
16
|
|
|
48
17
|
#if !defined(ANDROID)
|
|
@@ -16,7 +16,9 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
16
16
|
|
|
17
17
|
@interface ScrollableOptions : NSObject
|
|
18
18
|
|
|
19
|
+
@property (nonatomic, assign) BOOL contentInsetAdjustment;
|
|
19
20
|
@property (nonatomic, assign) CGFloat keyboardScrollOffset;
|
|
21
|
+
@property (nonatomic, assign) CGFloat keyboardOffset;
|
|
20
22
|
@property (nonatomic, assign) BOOL scrollingExpandsSheet;
|
|
21
23
|
@property (nonatomic, assign) facebook::react::TrueSheetViewTopScrollEdgeEffect topScrollEdgeEffect;
|
|
22
24
|
@property (nonatomic, assign) facebook::react::TrueSheetViewBottomScrollEdgeEffect bottomScrollEdgeEffect;
|
|
@@ -46,20 +48,20 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
46
48
|
@property (nonatomic, weak, nullable) id<TrueSheetContainerViewDelegate> delegate;
|
|
47
49
|
|
|
48
50
|
/**
|
|
49
|
-
*
|
|
51
|
+
* Options for scrollable behavior
|
|
50
52
|
*/
|
|
51
|
-
@property (nonatomic,
|
|
53
|
+
@property (nonatomic, strong, nullable) ScrollableOptions *scrollableOptions;
|
|
52
54
|
|
|
53
55
|
/**
|
|
54
|
-
*
|
|
56
|
+
* React tag of the user-provided scrollable within the content (see the `scrollableRef` prop)
|
|
55
57
|
*/
|
|
56
|
-
@property (nonatomic,
|
|
58
|
+
@property (nonatomic, assign) NSInteger scrollableHandle;
|
|
57
59
|
|
|
58
60
|
/**
|
|
59
|
-
* Whether the
|
|
60
|
-
*
|
|
61
|
+
* Whether the resolved scrollable's `contentInsetAdjustmentBehavior` is set to
|
|
62
|
+
* `automatic` — already gated by the sheet's `insetAdjustment`
|
|
61
63
|
*/
|
|
62
|
-
@property (nonatomic, assign) BOOL
|
|
64
|
+
@property (nonatomic, assign) BOOL contentInsetAdjustment;
|
|
63
65
|
|
|
64
66
|
/**
|
|
65
67
|
* Bottom safe-area inset the footer absorbs as padding — the footer
|
|
@@ -82,6 +84,11 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
82
84
|
*/
|
|
83
85
|
- (CGFloat)footerHeight;
|
|
84
86
|
|
|
87
|
+
/**
|
|
88
|
+
* Returns the bottom inset currently baked into the footer's height
|
|
89
|
+
*/
|
|
90
|
+
- (CGFloat)footerAppliedBottomInset;
|
|
91
|
+
|
|
85
92
|
/**
|
|
86
93
|
* Returns the current height of the peek view within the content
|
|
87
94
|
*/
|
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
#import "TrueSheetViewController.h"
|
|
18
18
|
#import "core/TrueSheetKeyboardObserver.h"
|
|
19
19
|
#import "utils/UIView+ScrollEdgeInteraction.h"
|
|
20
|
-
#import "utils/WindowUtil.h"
|
|
21
20
|
|
|
22
21
|
#import <react/renderer/components/TrueSheetSpec/ComponentDescriptors.h>
|
|
23
22
|
#import <react/renderer/components/TrueSheetSpec/EventEmitters.h>
|
|
@@ -33,7 +32,9 @@ using namespace facebook::react;
|
|
|
33
32
|
|
|
34
33
|
- (instancetype)init {
|
|
35
34
|
if (self = [super init]) {
|
|
35
|
+
_contentInsetAdjustment = YES;
|
|
36
36
|
_keyboardScrollOffset = 0;
|
|
37
|
+
_keyboardOffset = 0;
|
|
37
38
|
_scrollingExpandsSheet = YES;
|
|
38
39
|
_topScrollEdgeEffect = TrueSheetViewTopScrollEdgeEffect::Hidden;
|
|
39
40
|
_bottomScrollEdgeEffect = TrueSheetViewBottomScrollEdgeEffect::Hidden;
|
|
@@ -118,6 +119,10 @@ using namespace facebook::react;
|
|
|
118
119
|
return _footerView ? _footerView.frame.size.height : 0;
|
|
119
120
|
}
|
|
120
121
|
|
|
122
|
+
- (CGFloat)footerAppliedBottomInset {
|
|
123
|
+
return _footerView ? _footerView.appliedBottomInset : 0;
|
|
124
|
+
}
|
|
125
|
+
|
|
121
126
|
// Distance from the top of the content view to the bottom of the peek view.
|
|
122
127
|
// Includes the peek view's offset within the content (padding, views above it)
|
|
123
128
|
// so the peek detent reveals everything down to the peek content's bottom edge.
|
|
@@ -145,16 +150,14 @@ using namespace facebook::react;
|
|
|
145
150
|
- (void)setScrollableOptions:(ScrollableOptions *)scrollableOptions {
|
|
146
151
|
_scrollableOptions = scrollableOptions;
|
|
147
152
|
_contentView.keyboardScrollOffset = scrollableOptions ? scrollableOptions.keyboardScrollOffset : 0;
|
|
153
|
+
_contentView.keyboardOffset = scrollableOptions ? scrollableOptions.keyboardOffset : 0;
|
|
148
154
|
}
|
|
149
155
|
|
|
150
156
|
- (void)setupScrollable {
|
|
151
157
|
if (_contentView) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
}
|
|
156
|
-
_contentView.hasAutoDetent = _hasAutoDetent;
|
|
157
|
-
[_contentView setupScrollableWithBottomInset:bottomInset];
|
|
158
|
+
_contentView.scrollableHandle = _scrollableHandle;
|
|
159
|
+
_contentView.contentInsetAdjustment = _contentInsetAdjustment;
|
|
160
|
+
[_contentView setupScrollable];
|
|
158
161
|
[_contentView applyScrollEdgeEffects:_scrollableOptions];
|
|
159
162
|
if (@available(iOS 26.0, *)) {
|
|
160
163
|
[self setupEdgeInteractions];
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
#ifdef RCT_NEW_ARCH_ENABLED
|
|
10
10
|
|
|
11
|
+
#import <React/RCTMountingTransactionObserving.h>
|
|
11
12
|
#import <React/RCTSurfaceTouchHandler.h>
|
|
12
13
|
#import <React/RCTViewComponentView.h>
|
|
13
14
|
#import <UIKit/UIKit.h>
|
|
@@ -28,42 +29,57 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
28
29
|
|
|
29
30
|
@end
|
|
30
31
|
|
|
31
|
-
@interface TrueSheetContentView
|
|
32
|
+
@interface TrueSheetContentView
|
|
33
|
+
: RCTViewComponentView <TrueSheetKeyboardObserverDelegate, RCTMountingTransactionObserving>
|
|
32
34
|
|
|
33
35
|
@property (nonatomic, weak, nullable) id<TrueSheetContentViewDelegate> delegate;
|
|
34
36
|
@property (nonatomic, assign) CGFloat keyboardScrollOffset;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Adjustment added to the keyboard bottom inset applied to the detected
|
|
40
|
+
* scrollable — negative values reduce the inset (e.g. to cancel out safe-area
|
|
41
|
+
* padding already baked into the content's paddingBottom).
|
|
42
|
+
*/
|
|
43
|
+
@property (nonatomic, assign) CGFloat keyboardOffset;
|
|
44
|
+
|
|
35
45
|
@property (nonatomic, weak, nullable) TrueSheetKeyboardObserver *keyboardObserver;
|
|
36
46
|
|
|
37
47
|
/**
|
|
38
|
-
* Sibling footer view —
|
|
39
|
-
*
|
|
48
|
+
* Sibling footer view — a relative footer shields part of the keyboard's
|
|
49
|
+
* overlap from the inset; an absolute footer extends the caret reveal target.
|
|
40
50
|
*/
|
|
41
51
|
@property (nonatomic, weak, nullable) TrueSheetFooterView *footerView;
|
|
42
52
|
|
|
43
53
|
/**
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
54
|
+
* Content height measured unconstrained by the shadow node — the height the
|
|
55
|
+
* content wants regardless of container bounds (see
|
|
56
|
+
* TrueSheetContentViewShadowNode). Falls back to the frame height before the
|
|
57
|
+
* first state update.
|
|
47
58
|
*/
|
|
48
|
-
@property (nonatomic,
|
|
59
|
+
@property (nonatomic, readonly) CGFloat naturalHeight;
|
|
49
60
|
|
|
50
61
|
/**
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
* Falls back to the frame height when no ScrollView is pinned.
|
|
62
|
+
* React tag of the user-provided scrollable (see the `scrollableRef` prop).
|
|
63
|
+
* Setting a new handle clears the currently resolved ScrollView.
|
|
54
64
|
*/
|
|
55
|
-
@property (nonatomic,
|
|
65
|
+
@property (nonatomic, assign) NSInteger scrollableHandle;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Sets the resolved ScrollView's `contentInsetAdjustmentBehavior` to
|
|
69
|
+
* `automatic` while plugged so UIKit applies the bottom safe-area inset to
|
|
70
|
+
* the scroll content. The previous behavior is restored on clear.
|
|
71
|
+
*/
|
|
72
|
+
@property (nonatomic, assign) BOOL contentInsetAdjustment;
|
|
56
73
|
|
|
57
74
|
- (RCTScrollViewComponentView *_Nullable)findScrollView;
|
|
58
75
|
|
|
59
76
|
/**
|
|
60
|
-
*
|
|
61
|
-
* @param bottomInset Bottom content inset for the scroll view
|
|
77
|
+
* Resolve the ScrollView from `scrollableHandle`, wiring keyboard handling
|
|
62
78
|
*/
|
|
63
|
-
- (void)
|
|
79
|
+
- (void)setupScrollable;
|
|
64
80
|
|
|
65
81
|
/**
|
|
66
|
-
* Apply scroll edge effects to the
|
|
82
|
+
* Apply scroll edge effects to the detected scroll view (iOS 26+)
|
|
67
83
|
*/
|
|
68
84
|
- (void)applyScrollEdgeEffects:(nullable ScrollableOptions *)options;
|
|
69
85
|
|