367 lines
14 KiB
Diff
367 lines
14 KiB
Diff
diff --git a/node_modules/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts b/node_modules/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts
|
|
index 62f52a7..ca30165 100644
|
|
--- a/node_modules/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts
|
|
+++ b/node_modules/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts
|
|
@@ -426,9 +426,10 @@ export interface ViewStyle extends FlexStyle, ShadowStyleIOS, TransformsStyle {
|
|
*/
|
|
pointerEvents?: 'box-none' | 'none' | 'box-only' | 'auto' | undefined;
|
|
isolation?: 'auto' | 'isolate' | undefined;
|
|
- cursor?: CursorValue | undefined;
|
|
+ cursor?: CursorValue | string | undefined;
|
|
boxShadow?: ReadonlyArray<BoxShadowValue> | string | undefined;
|
|
filter?: ReadonlyArray<FilterFunction> | string | undefined;
|
|
+ transformOrigin?: string | (string | number)[] | undefined;
|
|
}
|
|
|
|
export type FontVariant =
|
|
@@ -536,7 +537,11 @@ export interface TextStyle extends TextStyleIOS, TextStyleAndroid, ViewStyle {
|
|
textShadowOffset?: {width: number; height: number} | undefined;
|
|
textShadowRadius?: number | undefined;
|
|
textTransform?: 'none' | 'capitalize' | 'uppercase' | 'lowercase' | undefined;
|
|
- userSelect?: 'auto' | 'none' | 'text' | 'contain' | 'all' | undefined;
|
|
+ userSelect?: 'auto' | 'none' | 'text' | 'contain' | 'all' | string | undefined;
|
|
+ cursor?: CursorValue | string | undefined;
|
|
+ boxShadow?: ReadonlyArray<BoxShadowValue> | string | undefined;
|
|
+ filter?: ReadonlyArray<FilterFunction> | string | undefined;
|
|
+ transformOrigin?: string | (string | number)[] | undefined;
|
|
}
|
|
|
|
/**
|
|
@@ -558,5 +563,8 @@ export interface ImageStyle extends FlexStyle, ShadowStyleIOS, TransformsStyle {
|
|
tintColor?: ColorValue | undefined;
|
|
opacity?: AnimatableNumericValue | undefined;
|
|
objectFit?: 'cover' | 'contain' | 'fill' | 'scale-down' | undefined;
|
|
- cursor?: CursorValue | undefined;
|
|
+ cursor?: CursorValue | string | undefined;
|
|
+ boxShadow?: ReadonlyArray<BoxShadowValue> | string | undefined;
|
|
+ filter?: ReadonlyArray<FilterFunction> | string | undefined;
|
|
+ transformOrigin?: string | (string | number)[] | undefined;
|
|
}
|
|
diff --git a/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTEnhancedScrollView.mm b/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTEnhancedScrollView.mm
|
|
index 93af874..106f8ec 100644
|
|
--- a/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTEnhancedScrollView.mm
|
|
+++ b/node_modules/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTEnhancedScrollView.mm
|
|
@@ -66,28 +66,51 @@
|
|
* ScrollView, we force it to be centered, but when you zoom or the content otherwise
|
|
* becomes larger than the ScrollView, there is no padding around the content but it
|
|
* can still fill the whole view.
|
|
+ * This implementation is based on https://petersteinberger.com/blog/2013/how-to-center-uiscrollview/.
|
|
*/
|
|
-- (void)setContentOffset:(CGPoint)contentOffset
|
|
+-(void)centerContentIfNeeded
|
|
{
|
|
- if (_isSetContentOffsetDisabled) {
|
|
+ if (!_centerContent) {
|
|
return;
|
|
}
|
|
|
|
- if (_centerContent && !CGSizeEqualToSize(self.contentSize, CGSizeZero)) {
|
|
- CGSize scrollViewSize = self.bounds.size;
|
|
- if (self.contentSize.width <= scrollViewSize.width) {
|
|
- contentOffset.x = -(scrollViewSize.width - self.contentSize.width) / 2.0;
|
|
- }
|
|
- if (self.contentSize.height <= scrollViewSize.height) {
|
|
- contentOffset.y = -(scrollViewSize.height - self.contentSize.height) / 2.0;
|
|
- }
|
|
+ CGSize contentSize = self.contentSize;
|
|
+ CGSize boundsSize = self.bounds.size;
|
|
+ if (CGSizeEqualToSize(contentSize, CGSizeZero) ||
|
|
+ CGSizeEqualToSize(boundsSize, CGSizeZero)) {
|
|
+ return;
|
|
}
|
|
|
|
+ CGFloat top = 0, left = 0;
|
|
+ if (contentSize.width < boundsSize.width) {
|
|
+ left = (boundsSize.width - contentSize.width) * 0.5f;
|
|
+ }
|
|
+ if (contentSize.height < boundsSize.height) {
|
|
+ top = (boundsSize.height - contentSize.height) * 0.5f;
|
|
+ }
|
|
+ self.contentInset = UIEdgeInsetsMake(top, left, top, left);
|
|
+}
|
|
+
|
|
+- (void)setContentOffset:(CGPoint)contentOffset
|
|
+{
|
|
+ if (_isSetContentOffsetDisabled) {
|
|
+ return;
|
|
+ }
|
|
super.contentOffset = CGPointMake(
|
|
RCTSanitizeNaNValue(contentOffset.x, @"scrollView.contentOffset.x"),
|
|
RCTSanitizeNaNValue(contentOffset.y, @"scrollView.contentOffset.y"));
|
|
}
|
|
|
|
+- (void)setFrame:(CGRect)frame {
|
|
+ [super setFrame:frame];
|
|
+ [self centerContentIfNeeded];
|
|
+}
|
|
+
|
|
+- (void)didAddSubview:(UIView *)subview {
|
|
+ [super didAddSubview:subview];
|
|
+ [self centerContentIfNeeded];
|
|
+}
|
|
+
|
|
- (BOOL)touchesShouldCancelInContentView:(UIView *)view
|
|
{
|
|
if ([_overridingDelegate respondsToSelector:@selector(touchesShouldCancelInContentView:)]) {
|
|
@@ -257,6 +280,10 @@
|
|
}
|
|
}
|
|
|
|
+- (void)scrollViewDidZoom:(__unused UIScrollView *)scrollView {
|
|
+ [self centerContentIfNeeded];
|
|
+}
|
|
+
|
|
#pragma mark -
|
|
|
|
- (BOOL)isHorizontal:(UIScrollView *)scrollView
|
|
diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h
|
|
index e9b330f..ec5f58c 100644
|
|
--- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h
|
|
+++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.h
|
|
@@ -15,5 +15,8 @@
|
|
@property (nonatomic, copy) NSString *title;
|
|
@property (nonatomic, copy) RCTDirectEventBlock onRefresh;
|
|
@property (nonatomic, weak) UIScrollView *scrollView;
|
|
+@property (nonatomic, copy) UIColor *customTintColor;
|
|
+
|
|
+- (void)forwarderBeginRefreshing;
|
|
|
|
@end
|
|
diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m
|
|
index 53bfd04..ff1b1ed 100644
|
|
--- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m
|
|
+++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControl.m
|
|
@@ -23,6 +23,7 @@
|
|
UIColor *_titleColor;
|
|
CGFloat _progressViewOffset;
|
|
BOOL _hasMovedToWindow;
|
|
+ UIColor *_customTintColor;
|
|
}
|
|
|
|
- (instancetype)init
|
|
@@ -58,6 +59,12 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder)
|
|
_isInitialRender = false;
|
|
}
|
|
|
|
+- (void)didMoveToSuperview
|
|
+{
|
|
+ [super didMoveToSuperview];
|
|
+ [self setTintColor:_customTintColor];
|
|
+}
|
|
+
|
|
- (void)didMoveToWindow
|
|
{
|
|
[super didMoveToWindow];
|
|
@@ -221,4 +228,50 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder)
|
|
}
|
|
}
|
|
|
|
+// Fix for https://github.com/facebook/react-native/issues/43388
|
|
+// A bug in iOS 17.4 causes the haptic to not play when refreshing if the tintColor
|
|
+// is set before the refresh control gets added to the scrollview. We'll call this
|
|
+// function whenever the superview changes. We'll also call it if the value of customTintColor
|
|
+// changes.
|
|
+- (void)setTintColor:(UIColor *)tintColor
|
|
+{
|
|
+ if ([self.superview isKindOfClass:[UIScrollView class]] && self.tintColor != tintColor) {
|
|
+ [super setTintColor:tintColor];
|
|
+ }
|
|
+}
|
|
+
|
|
+// This method is used by Bluesky's ExpoScrollForwarder. This allows other React Native
|
|
+// libraries to perform a refresh of a scrollview and access the refresh control's onRefresh
|
|
+// function.
|
|
+- (void)forwarderBeginRefreshing
|
|
+{
|
|
+ _refreshingProgrammatically = NO;
|
|
+
|
|
+ [self sizeToFit];
|
|
+
|
|
+ if (!self.scrollView) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ UIScrollView *scrollView = (UIScrollView *)self.scrollView;
|
|
+
|
|
+ [UIView animateWithDuration:0.3
|
|
+ delay:0
|
|
+ options:UIViewAnimationOptionBeginFromCurrentState
|
|
+ animations:^(void) {
|
|
+ // Whenever we call this method, the scrollview will always be at a position of
|
|
+ // -130 or less. Scrolling back to -65 simulates the default behavior of RCTRefreshControl
|
|
+ [scrollView setContentOffset:CGPointMake(0, -65)];
|
|
+ }
|
|
+ completion:^(__unused BOOL finished) {
|
|
+ [super beginRefreshing];
|
|
+ [self setCurrentRefreshingState:super.refreshing];
|
|
+
|
|
+ if (self->_onRefresh) {
|
|
+ self->_onRefresh(nil);
|
|
+ }
|
|
+ }
|
|
+ ];
|
|
+}
|
|
+
|
|
@end
|
|
diff --git a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControlManager.m b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControlManager.m
|
|
index 40aaf9c..1c60164 100644
|
|
--- a/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControlManager.m
|
|
+++ b/node_modules/react-native/React/Views/RefreshControl/RCTRefreshControlManager.m
|
|
@@ -22,11 +22,12 @@ RCT_EXPORT_MODULE()
|
|
|
|
RCT_EXPORT_VIEW_PROPERTY(onRefresh, RCTDirectEventBlock)
|
|
RCT_EXPORT_VIEW_PROPERTY(refreshing, BOOL)
|
|
-RCT_EXPORT_VIEW_PROPERTY(tintColor, UIColor)
|
|
RCT_EXPORT_VIEW_PROPERTY(title, NSString)
|
|
RCT_EXPORT_VIEW_PROPERTY(titleColor, UIColor)
|
|
RCT_EXPORT_VIEW_PROPERTY(progressViewOffset, CGFloat)
|
|
|
|
+RCT_REMAP_VIEW_PROPERTY(tintColor, customTintColor, UIColor)
|
|
+
|
|
RCT_EXPORT_METHOD(setNativeRefreshing : (nonnull NSNumber *)viewTag toRefreshing : (BOOL)refreshing)
|
|
{
|
|
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
|
diff --git a/node_modules/react-native/React/Views/ScrollView/RCTScrollView.m b/node_modules/react-native/React/Views/ScrollView/RCTScrollView.m
|
|
index 6f41b5c..9b4f77f 100644
|
|
--- a/node_modules/react-native/React/Views/ScrollView/RCTScrollView.m
|
|
+++ b/node_modules/react-native/React/Views/ScrollView/RCTScrollView.m
|
|
@@ -159,26 +159,8 @@
|
|
return !shouldDisableScrollInteraction;
|
|
}
|
|
|
|
-/*
|
|
- * Automatically centers the content such that if the content is smaller than the
|
|
- * ScrollView, we force it to be centered, but when you zoom or the content otherwise
|
|
- * becomes larger than the ScrollView, there is no padding around the content but it
|
|
- * can still fill the whole view.
|
|
- */
|
|
- (void)setContentOffset:(CGPoint)contentOffset
|
|
{
|
|
- UIView *contentView = [self contentView];
|
|
- if (contentView && _centerContent && !CGSizeEqualToSize(contentView.frame.size, CGSizeZero)) {
|
|
- CGSize subviewSize = contentView.frame.size;
|
|
- CGSize scrollViewSize = self.bounds.size;
|
|
- if (subviewSize.width <= scrollViewSize.width) {
|
|
- contentOffset.x = -(scrollViewSize.width - subviewSize.width) / 2.0;
|
|
- }
|
|
- if (subviewSize.height <= scrollViewSize.height) {
|
|
- contentOffset.y = -(scrollViewSize.height - subviewSize.height) / 2.0;
|
|
- }
|
|
- }
|
|
-
|
|
super.contentOffset = CGPointMake(
|
|
RCTSanitizeNaNValue(contentOffset.x, @"scrollView.contentOffset.x"),
|
|
RCTSanitizeNaNValue(contentOffset.y, @"scrollView.contentOffset.y"));
|
|
@@ -433,6 +415,11 @@ static inline void RCTApplyTransformationAccordingLayoutDirection(
|
|
// Does nothing
|
|
}
|
|
|
|
+- (void)setFrame:(CGRect)frame {
|
|
+ [super setFrame:frame];
|
|
+ [self centerContentIfNeeded];
|
|
+}
|
|
+
|
|
- (void)insertReactSubview:(UIView *)view atIndex:(NSInteger)atIndex
|
|
{
|
|
[super insertReactSubview:view atIndex:atIndex];
|
|
@@ -449,6 +436,8 @@ static inline void RCTApplyTransformationAccordingLayoutDirection(
|
|
_contentView = view;
|
|
RCTApplyTransformationAccordingLayoutDirection(_contentView, self.reactLayoutDirection);
|
|
[_scrollView addSubview:view];
|
|
+
|
|
+ [self centerContentIfNeeded];
|
|
}
|
|
}
|
|
|
|
@@ -658,9 +647,46 @@ static inline void RCTApplyTransformationAccordingLayoutDirection(
|
|
}
|
|
|
|
RCT_SCROLL_EVENT_HANDLER(scrollViewWillBeginDecelerating, onMomentumScrollBegin)
|
|
-RCT_SCROLL_EVENT_HANDLER(scrollViewDidZoom, onScroll)
|
|
RCT_SCROLL_EVENT_HANDLER(scrollViewDidScrollToTop, onScrollToTop)
|
|
|
|
+-(void)scrollViewDidZoom : (UIScrollView *)scrollView
|
|
+{
|
|
+ [self centerContentIfNeeded];
|
|
+
|
|
+ RCT_SEND_SCROLL_EVENT(onScroll, nil);
|
|
+ RCT_FORWARD_SCROLL_EVENT(scrollViewDidZoom : scrollView);
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Automatically centers the content such that if the content is smaller than the
|
|
+ * ScrollView, we force it to be centered, but when you zoom or the content otherwise
|
|
+ * becomes larger than the ScrollView, there is no padding around the content but it
|
|
+ * can still fill the whole view.
|
|
+ * This implementation is based on https://petersteinberger.com/blog/2013/how-to-center-uiscrollview/.
|
|
+ */
|
|
+-(void)centerContentIfNeeded
|
|
+{
|
|
+ if (!_scrollView.centerContent) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ CGSize contentSize = self.contentSize;
|
|
+ CGSize boundsSize = self.bounds.size;
|
|
+ if (CGSizeEqualToSize(contentSize, CGSizeZero) ||
|
|
+ CGSizeEqualToSize(boundsSize, CGSizeZero)) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ CGFloat top = 0, left = 0;
|
|
+ if (contentSize.width < boundsSize.width) {
|
|
+ left = (boundsSize.width - contentSize.width) * 0.5f;
|
|
+ }
|
|
+ if (contentSize.height < boundsSize.height) {
|
|
+ top = (boundsSize.height - contentSize.height) * 0.5f;
|
|
+ }
|
|
+ _scrollView.contentInset = UIEdgeInsetsMake(top, left, top, left);
|
|
+}
|
|
+
|
|
- (void)addScrollListener:(NSObject<UIScrollViewDelegate> *)scrollListener
|
|
{
|
|
[_scrollListeners addObject:scrollListener];
|
|
@@ -939,6 +965,7 @@ RCT_SCROLL_EVENT_HANDLER(scrollViewDidScrollToTop, onScrollToTop)
|
|
CGSize contentSize = self.contentSize;
|
|
if (!CGSizeEqualToSize(_scrollView.contentSize, contentSize)) {
|
|
_scrollView.contentSize = contentSize;
|
|
+ [self centerContentIfNeeded];
|
|
}
|
|
}
|
|
|
|
@@ -1061,6 +1088,22 @@ RCT_SET_AND_PRESERVE_OFFSET(setShowsHorizontalScrollIndicator, showsHorizontalSc
|
|
RCT_SET_AND_PRESERVE_OFFSET(setShowsVerticalScrollIndicator, showsVerticalScrollIndicator, BOOL)
|
|
RCT_SET_AND_PRESERVE_OFFSET(setZoomScale, zoomScale, CGFloat);
|
|
|
|
+- (void)setScrollIndicatorInsets:(UIEdgeInsets)value
|
|
+{
|
|
+ [_scrollView setScrollIndicatorInsets:value];
|
|
+}
|
|
+
|
|
+- (UIEdgeInsets)scrollIndicatorInsets
|
|
+{
|
|
+ UIEdgeInsets verticalScrollIndicatorInsets = [_scrollView verticalScrollIndicatorInsets];
|
|
+ UIEdgeInsets horizontalScrollIndicatorInsets = [_scrollView horizontalScrollIndicatorInsets];
|
|
+ return UIEdgeInsetsMake(
|
|
+ verticalScrollIndicatorInsets.top,
|
|
+ horizontalScrollIndicatorInsets.left,
|
|
+ verticalScrollIndicatorInsets.bottom,
|
|
+ horizontalScrollIndicatorInsets.right);
|
|
+}
|
|
+
|
|
- (void)setAutomaticallyAdjustsScrollIndicatorInsets:(BOOL)automaticallyAdjusts API_AVAILABLE(ios(13.0))
|
|
{
|
|
// `automaticallyAdjustsScrollIndicatorInsets` is available since iOS 13.
|
|
diff --git a/node_modules/react-native/React/Views/ScrollView/RCTScrollViewManager.m b/node_modules/react-native/React/Views/ScrollView/RCTScrollViewManager.m
|
|
index cd1e7eb..c1d0172 100644
|
|
--- a/node_modules/react-native/React/Views/ScrollView/RCTScrollViewManager.m
|
|
+++ b/node_modules/react-native/React/Views/ScrollView/RCTScrollViewManager.m
|
|
@@ -83,6 +83,7 @@ RCT_EXPORT_VIEW_PROPERTY(showsVerticalScrollIndicator, BOOL)
|
|
RCT_EXPORT_VIEW_PROPERTY(scrollEventThrottle, NSTimeInterval)
|
|
RCT_EXPORT_VIEW_PROPERTY(zoomScale, CGFloat)
|
|
RCT_EXPORT_VIEW_PROPERTY(contentInset, UIEdgeInsets)
|
|
+RCT_EXPORT_VIEW_PROPERTY(scrollIndicatorInsets, UIEdgeInsets)
|
|
RCT_EXPORT_VIEW_PROPERTY(verticalScrollIndicatorInsets, UIEdgeInsets)
|
|
RCT_EXPORT_VIEW_PROPERTY(scrollToOverflowEnabled, BOOL)
|
|
RCT_EXPORT_VIEW_PROPERTY(snapToInterval, int)
|