react-native-windows 0.66.5 → 0.67.0-preview.4
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/.flowconfig +2 -1
- package/CHANGELOG.json +934 -102
- package/CHANGELOG.md +358 -43
- package/Libraries/ActionSheetIOS/ActionSheetIOS.js +14 -1
- package/Libraries/ActionSheetIOS/NativeActionSheetManager.js +2 -0
- package/Libraries/Alert/Alert.windows.js +48 -21
- package/Libraries/Alert/NativeDialogManagerWindows.js +49 -0
- package/Libraries/Animated/AnimatedEvent.js +23 -4
- package/Libraries/Animated/NativeAnimatedHelper.js +2 -2
- package/Libraries/Animated/components/AnimatedImage.js +3 -3
- package/Libraries/Animated/components/AnimatedScrollView.js +3 -3
- package/Libraries/Animated/components/AnimatedText.js +3 -3
- package/Libraries/Animated/components/AnimatedView.js +1 -3
- package/Libraries/Animated/createAnimatedComponent.js +3 -34
- package/Libraries/Components/Button.js +3 -0
- package/Libraries/Components/Button.windows.js +70 -38
- package/Libraries/Components/DatePicker/DatePickerIOS.ios.js +3 -6
- package/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.android.js +4 -7
- package/Libraries/Components/Flyout/Flyout.js +3 -3
- package/Libraries/Components/Flyout/Flyout.js.map +1 -1
- package/Libraries/Components/Flyout/FlyoutProps.d.ts +4 -0
- package/Libraries/Components/Flyout/FlyoutProps.js.map +1 -1
- package/Libraries/Components/Glyph/Glyph.js +2 -2
- package/Libraries/Components/Glyph/Glyph.js.map +1 -1
- package/Libraries/Components/Keyboard/KeyboardExt.js +4 -3
- package/Libraries/Components/Keyboard/KeyboardExt.js.map +1 -1
- package/Libraries/Components/Popup/Popup.js +3 -3
- package/Libraries/Components/Popup/Popup.js.map +1 -1
- package/Libraries/Components/ScrollView/AndroidHorizontalScrollViewNativeComponent.js +1 -0
- package/Libraries/Components/ScrollView/ScrollView.js +17 -16
- package/Libraries/Components/ScrollView/ScrollViewStickyHeader.js +268 -252
- package/Libraries/Components/View/View.js +1 -1
- package/Libraries/Components/View/View.windows.js +1 -1
- package/Libraries/Components/View/ViewAccessibility.js +1 -1
- package/Libraries/Components/View/ViewAccessibility.windows.js +1 -1
- package/Libraries/Components/View/ViewWindows.js +1 -1
- package/Libraries/Components/View/ViewWindows.js.map +1 -1
- package/Libraries/Components/View/ViewWindowsProps.d.ts +42 -2
- package/Libraries/Components/View/ViewWindowsProps.js.map +1 -1
- package/Libraries/Core/ExceptionsManager.js +45 -80
- package/Libraries/Core/ExtendedError.js +0 -1
- package/Libraries/Core/ReactNativeVersion.js +2 -2
- package/Libraries/Core/setUpBatchedBridge.js +1 -1
- package/Libraries/Core/setUpGlobals.js +2 -4
- package/Libraries/Core/setUpTimers.js +2 -2
- package/Libraries/Image/Image.ios.js +6 -0
- package/Libraries/Image/Image.windows.js +6 -0
- package/Libraries/Image/ImageBackground.js +10 -8
- package/Libraries/Image/ImageProps.js +28 -0
- package/Libraries/LogBox/Data/LogBoxData.js +18 -19
- package/Libraries/LogBox/UI/LogBoxImages/alert-triangle.png +0 -0
- package/Libraries/LogBox/UI/LogBoxImages/chevron-left.png +0 -0
- package/Libraries/LogBox/UI/LogBoxImages/chevron-right.png +0 -0
- package/Libraries/LogBox/UI/LogBoxImages/close.png +0 -0
- package/Libraries/LogBox/UI/LogBoxImages/loader.png +0 -0
- package/Libraries/NewAppScreen/components/logo.png +0 -0
- package/Libraries/PermissionsAndroid/NativePermissionsAndroid.js +2 -1
- package/Libraries/PermissionsAndroid/PermissionsAndroid.js +2 -0
- package/Libraries/Pressability/Pressability.js +13 -13
- package/Libraries/Pressability/Pressability.windows.js +13 -13
- package/Libraries/Pressability/PressabilityPerformanceEventEmitter.js +1 -1
- package/Libraries/ReactNative/AppRegistry.js +4 -2
- package/Libraries/Renderer/implementations/ReactFabric-dev.fb.js +1569 -875
- package/Libraries/Renderer/implementations/ReactFabric-prod.fb.js +529 -319
- package/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js +570 -362
- package/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js +1592 -891
- package/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js +521 -311
- package/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js +562 -354
- package/Libraries/Share/Share.js +1 -1
- package/Libraries/StyleSheet/normalizeColor.js +2 -2
- package/Libraries/Text/Text.windows.js +1 -0
- package/Libraries/Text/TextNativeComponent.windows.js +72 -0
- package/Libraries/Text/TextProps.js +1 -7
- package/Libraries/TurboModule/TurboModuleRegistry.js +1 -1
- package/Libraries/Utilities/HMRClient.js +1 -1
- package/Microsoft.ReactNative/ABIViewManager.cpp +10 -1
- package/Microsoft.ReactNative/ABIViewManager.h +3 -0
- package/Microsoft.ReactNative/Base/CoreNativeModules.cpp +0 -6
- package/Microsoft.ReactNative/IReactDispatcher.cpp +16 -1
- package/Microsoft.ReactNative/IViewManager.idl +25 -0
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +35 -6
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters +60 -0
- package/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp +3 -4
- package/Microsoft.ReactNative/Modules/AccessibilityInfoModule.h +3 -3
- package/Microsoft.ReactNative/Modules/AlertModule.cpp +57 -14
- package/Microsoft.ReactNative/Modules/AlertModule.h +17 -24
- package/Microsoft.ReactNative/Modules/Animated/InterpolationAnimatedNode.cpp +4 -2
- package/Microsoft.ReactNative/Modules/Animated/PropsAnimatedNode.cpp +3 -1
- package/Microsoft.ReactNative/Modules/AppStateModule.cpp +8 -6
- package/Microsoft.ReactNative/Modules/AppStateModule.h +6 -9
- package/Microsoft.ReactNative/Modules/DeviceInfoModule.cpp +34 -22
- package/Microsoft.ReactNative/Modules/DeviceInfoModule.h +8 -4
- package/Microsoft.ReactNative/Modules/I18nManagerModule.cpp +6 -4
- package/Microsoft.ReactNative/Modules/I18nManagerModule.h +3 -2
- package/Microsoft.ReactNative/Modules/ImageViewManagerModule.cpp +47 -95
- package/Microsoft.ReactNative/Modules/ImageViewManagerModule.h +28 -17
- package/Microsoft.ReactNative/Modules/LinkingManagerModule.cpp +14 -4
- package/Microsoft.ReactNative/Modules/NativeUIManager.cpp +1 -1
- package/Microsoft.ReactNative/Modules/PaperUIManagerModule.cpp +82 -66
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +14 -1
- package/Microsoft.ReactNative/ReactInstanceSettings.idl +3 -1
- package/Microsoft.ReactNative/ReactPointerEventArgs.cpp +37 -0
- package/Microsoft.ReactNative/ReactPointerEventArgs.h +28 -0
- package/Microsoft.ReactNative/ReactPointerEventArgs.idl +67 -0
- package/Microsoft.ReactNative/Utils/TextTransform.h +1 -1
- package/Microsoft.ReactNative/Utils/XamlIslandUtils.cpp +24 -10
- package/Microsoft.ReactNative/Utils/XamlIslandUtils.h +4 -2
- package/Microsoft.ReactNative/Version.rc +2 -19
- package/Microsoft.ReactNative/Views/FlyoutViewManager.cpp +57 -2
- package/Microsoft.ReactNative/Views/FrameworkElementTransferProperties.cpp +3 -0
- package/Microsoft.ReactNative/Views/FrameworkElementViewManager.cpp +7 -2
- package/Microsoft.ReactNative/Views/Image/ImageViewManager.cpp +16 -6
- package/Microsoft.ReactNative/Views/Image/ReactImage.cpp +18 -11
- package/Microsoft.ReactNative/Views/Image/ReactImage.h +3 -1
- package/Microsoft.ReactNative/Views/RawTextViewManager.cpp +4 -53
- package/Microsoft.ReactNative/Views/RawTextViewManager.h +0 -3
- package/Microsoft.ReactNative/Views/ShadowNodeBase.h +5 -0
- package/Microsoft.ReactNative/Views/Text/TextHighlighterVisitor.cpp +52 -0
- package/Microsoft.ReactNative/Views/Text/TextHighlighterVisitor.h +37 -0
- package/Microsoft.ReactNative/Views/Text/TextHitTestUtils.cpp +343 -0
- package/Microsoft.ReactNative/Views/Text/TextHitTestUtils.h +13 -0
- package/Microsoft.ReactNative/Views/Text/TextHitTestVisitor.cpp +76 -0
- package/Microsoft.ReactNative/Views/Text/TextHitTestVisitor.h +32 -0
- package/Microsoft.ReactNative/Views/Text/TextParentVisitor.cpp +12 -0
- package/Microsoft.ReactNative/Views/Text/TextParentVisitor.h +19 -0
- package/Microsoft.ReactNative/Views/Text/TextPropertyChangedParentVisitor.cpp +80 -0
- package/Microsoft.ReactNative/Views/Text/TextPropertyChangedParentVisitor.h +43 -0
- package/Microsoft.ReactNative/Views/Text/TextTransformParentVisitor.cpp +21 -0
- package/Microsoft.ReactNative/Views/Text/TextTransformParentVisitor.h +23 -0
- package/Microsoft.ReactNative/Views/Text/TextTransformVisitor.cpp +70 -0
- package/Microsoft.ReactNative/Views/Text/TextTransformVisitor.h +34 -0
- package/Microsoft.ReactNative/Views/Text/TextVisitor.cpp +56 -0
- package/Microsoft.ReactNative/Views/Text/TextVisitor.h +34 -0
- package/Microsoft.ReactNative/Views/Text/TextVisitorScope.h +35 -0
- package/Microsoft.ReactNative/Views/Text/TextVisitors.h +47 -0
- package/Microsoft.ReactNative/Views/TextViewManager.cpp +112 -103
- package/Microsoft.ReactNative/Views/TextViewManager.h +6 -12
- package/Microsoft.ReactNative/Views/TouchEventHandler.cpp +171 -129
- package/Microsoft.ReactNative/Views/TouchEventHandler.h +19 -15
- package/Microsoft.ReactNative/Views/ViewManagerBase.cpp +31 -0
- package/Microsoft.ReactNative/Views/ViewManagerBase.h +2 -0
- package/Microsoft.ReactNative/Views/ViewViewManager.cpp +0 -5
- package/Microsoft.ReactNative/Views/VirtualTextViewManager.cpp +21 -91
- package/Microsoft.ReactNative/Views/VirtualTextViewManager.h +5 -8
- package/Microsoft.ReactNative/XamlView.h +3 -3
- package/Microsoft.ReactNative/packages.config +1 -1
- package/Microsoft.ReactNative.Cxx/NativeModules.h +114 -0
- package/Microsoft.ReactNative.Cxx/VersionMacros.h +19 -0
- package/PropertySheets/External/Microsoft.ReactNative.Common.props +2 -0
- package/PropertySheets/External/Microsoft.ReactNative.Uwp.CppApp.props +1 -0
- package/PropertySheets/External/Microsoft.ReactNative.Uwp.CppLib.props +1 -0
- package/PropertySheets/Generated/PackageVersion.g.props +19 -0
- package/PropertySheets/PackageVersionDefinitions.props +28 -0
- package/PropertySheets/WinUI.props +1 -1
- package/Scripts/Microsoft.ReactNative.Managed.nuspec +1 -1
- package/Scripts/copyRNLibraries.js +12 -0
- package/Scripts/rnw-dependencies.ps1 +25 -24
- package/Shared/HermesSamplingProfiler.cpp +3 -21
- package/Shared/Modules/PlatformConstantsModule.cpp +1 -15
- package/Shared/Utils.cpp +58 -0
- package/Shared/Utils.h +3 -0
- package/codegen/NativeAccessibilityInfoSpec.g.h +9 -9
- package/codegen/NativeAccessibilityManagerSpec.g.h +49 -21
- package/codegen/NativeActionSheetManagerSpec.g.h +62 -6
- package/codegen/NativeAlertManagerSpec.g.h +4 -4
- package/codegen/NativeAnimatedModuleSpec.g.h +10 -10
- package/codegen/NativeAnimatedTurboModuleSpec.g.h +10 -10
- package/codegen/NativeAppStateSpec.g.h +25 -3
- package/codegen/NativeAppearanceSpec.g.h +3 -3
- package/codegen/NativeAsyncLocalStorageSpec.g.h +66 -18
- package/codegen/NativeAsyncSQLiteDBStorageSpec.g.h +66 -18
- package/codegen/NativeBlobModuleSpec.g.h +24 -6
- package/codegen/NativeBugReportingSpec.g.h +3 -3
- package/codegen/NativeDatePickerAndroidSpec.g.h +3 -3
- package/codegen/NativeDevLoadingViewSpec.g.h +3 -3
- package/codegen/NativeDeviceInfoSpec.g.h +18 -0
- package/codegen/NativeDialogManagerAndroidSpec.g.h +28 -4
- package/codegen/NativeDialogManagerWindowsSpec.g.h +77 -0
- package/codegen/NativeExceptionsManagerSpec.g.h +11 -11
- package/codegen/NativeFileReaderModuleSpec.g.h +6 -6
- package/codegen/NativeFrameRateLoggerSpec.g.h +11 -3
- package/codegen/NativeI18nManagerSpec.g.h +20 -0
- package/codegen/NativeImageEditorSpec.g.h +30 -6
- package/codegen/NativeImageLoaderAndroidSpec.g.h +6 -6
- package/codegen/NativeImageLoaderIOSSpec.g.h +6 -6
- package/codegen/NativeImagePickerIOSSpec.g.h +28 -12
- package/codegen/NativeImageStoreAndroidSpec.g.h +3 -3
- package/codegen/NativeImageStoreIOSSpec.g.h +21 -9
- package/codegen/NativeIntentAndroidSpec.g.h +3 -3
- package/codegen/NativeJSCHeapCaptureSpec.g.h +3 -3
- package/codegen/NativeJSCSamplingProfilerSpec.g.h +3 -3
- package/codegen/NativeJSDevSupportSpec.g.h +18 -0
- package/codegen/NativeNetworkingAndroidSpec.g.h +6 -6
- package/codegen/NativeNetworkingIOSSpec.g.h +26 -6
- package/codegen/NativePermissionsAndroidSpec.g.h +3 -3
- package/codegen/NativePlatformConstantsAndroidSpec.g.h +48 -0
- package/codegen/NativePlatformConstantsIOSSpec.g.h +38 -0
- package/codegen/NativePlatformConstantsWinSpec.g.h +32 -0
- package/codegen/NativePushNotificationManagerIOSSpec.g.h +35 -25
- package/codegen/NativeRedBoxSpec.g.h +3 -3
- package/codegen/NativeSampleTurboModuleSpec.g.h +32 -12
- package/codegen/NativeSegmentFetcherSpec.g.h +6 -6
- package/codegen/NativeSettingsManagerSpec.g.h +22 -6
- package/codegen/NativeShareModuleSpec.g.h +11 -3
- package/codegen/NativeSourceCodeSpec.g.h +16 -0
- package/codegen/NativeStatusBarManagerAndroidSpec.g.h +21 -3
- package/codegen/NativeStatusBarManagerIOSSpec.g.h +30 -6
- package/codegen/NativeToastAndroidSpec.g.h +24 -0
- package/codegen/NativeUIManagerSpec.g.h +63 -63
- package/codegen/NativeVibrationSpec.g.h +3 -3
- package/codegen/NativeWebSocketModuleSpec.g.h +9 -3
- package/index.js +15 -10
- package/index.windows.js +15 -10
- package/jest/mockModal.js +31 -0
- package/jest/setup.js +5 -3
- package/just-task.js +2 -1
- package/package.json +23 -20
- package/rntypes/BatchedBridge.d.ts +23 -0
- package/rntypes/Devtools.d.ts +20 -0
- package/rntypes/LaunchScreen.d.ts +9 -0
- package/rntypes/globals.d.ts +496 -0
- package/rntypes/index.d.ts +9966 -0
- package/rntypes/legacy-properties.d.ts +266 -0
- package/template/cpp-app/proj/MyApp.vcxproj +0 -5
- package/template/cpp-app/src/pch.h +1 -0
- package/template/cpp-lib/src/pch.h +3 -0
- package/template/cs-app/proj/MyApp.csproj +0 -6
- package/typings-index.d.ts +2 -1
- package/typings-index.js +7 -5
- package/typings-index.js.map +1 -1
- package/Libraries/Components/DatePickerAndroid/DatePickerAndroid.android.js +0 -87
- package/Libraries/Components/DatePickerAndroid/DatePickerAndroid.ios.js +0 -30
- package/Libraries/Components/DatePickerAndroid/DatePickerAndroid.windows.js +0 -30
- package/Libraries/Components/DatePickerAndroid/DatePickerAndroidTypes.js +0 -30
- package/Libraries/Components/StaticContainer.react.js +0 -51
- package/Libraries/Components/Touchable/ensurePositiveDelayProps.js +0 -25
- package/Libraries/Interaction/InteractionMixin.js +0 -54
- package/Libraries/ReactNative/queryLayoutByID.js +0 -58
- package/template/cpp-app/keys/MyApp_TemporaryKey.pfx +0 -0
- package/template/cs-app/keys/MyApp_TemporaryKey.pfx +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Popup.js","sourceRoot":"","sources":["../../../src/Libraries/Components/Popup/Popup.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,YAAY,CAAC;;;;;;AAEb,kDAA0B;AAC1B,+CAAgF;AAGhF,MAAM,MAAM,GAAG,yBAAU,CAAC,MAAM,CAAC;IAC/B,QAAQ,EAAE;QACR,QAAQ,EAAE,UAAU;KACrB;CACF,CAAC,CAAC;AAOH,MAAM,QAAQ,GAAG,qCAAsB,
|
|
1
|
+
{"version":3,"file":"Popup.js","sourceRoot":"","sources":["../../../src/Libraries/Components/Popup/Popup.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,YAAY,CAAC;;;;;;AAEb,kDAA0B;AAC1B,+CAAgF;AAGhF,MAAM,MAAM,GAAG,yBAAU,CAAC,MAAM,CAAC;IAC/B,QAAQ,EAAE;QACR,QAAQ,EAAE,UAAU;KACrB;CACF,CAAC,CAAC;AAOH,MAAM,QAAQ,GAAG,IAAA,qCAAsB,EAAc,UAAU,CAAC,CAAC;AAEjE;;;;;;;GAOG;AACH,MAAa,KAAM,SAAQ,eAAK,CAAC,SAAyC;IACjE,MAAM,CAAC,wBAAwB,CACpC,SAAsB,EACtB,SAA4B;QAE5B,mGAAmG;QACnG,IAAI,SAAS,CAAC,SAAS,KAAK,SAAS,CAAC,MAAM,EAAE;YAC5C,qEAAqE;YACrE,MAAM,SAAS,GAAkB,IAAA,6BAAc,EAC7C,SAAS,CAAC,MAIqB,CAChC,CAAC;YAEF,OAAO;gBACL,MAAM,EAAE,SAAS;gBACjB,SAAS,EAAE,SAAS,CAAC,MAAM;aAC5B,CAAC;SACH;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,YAAY,KAAkB;QAC5B,KAAK,CAAC,KAAK,CAAC,CAAC;QACb,IAAI,CAAC,KAAK,GAAG,EAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAC,CAAC;IACpD,CAAC;IAEM,MAAM;QACX,MAAM,KAAK,GAAG,EAAC,GAAG,IAAI,CAAC,KAAK,EAAC,CAAC;QAC9B,KAAK,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAElD,OAAO,8BAAC,QAAQ,OAAK,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAI,CAAC;IAC5D,CAAC;CACF;AApCD,sBAoCC","sourcesContent":["/**\n * Copyright (c) Microsoft Corporation.\n * Licensed under the MIT License.\n * @format\n */\n'use strict';\n\nimport React from 'react';\nimport {findNodeHandle, requireNativeComponent, StyleSheet} from 'react-native';\nimport {IPopupProps} from './PopupProps';\n\nconst styles = StyleSheet.create({\n rctPopup: {\n position: 'absolute',\n },\n});\n\nexport interface IPopupTargetState {\n target?: number | null;\n targetRef?: React.ReactNode;\n}\n\nconst RCTPopup = requireNativeComponent<IPopupProps>('RCTPopup');\n\n/**\n * Renders a popup component.\n *\n * This is a controlled component that requires an `onDismiss` callback that\n * updates the `isOpen` prop in order for the component to reflect user actions.\n *\n * @keyword popup\n */\nexport class Popup extends React.Component<IPopupProps, IPopupTargetState> {\n public static getDerivedStateFromProps(\n nextProps: IPopupProps,\n prevState: IPopupTargetState,\n ): IPopupTargetState {\n // Check if we're given a new target property; we need to resolve it to a node handle before render\n if (prevState.targetRef !== nextProps.target) {\n // Map the 'target' property to a node tag to use in the native layer\n const newTarget: number | null = findNodeHandle(\n nextProps.target as\n | null\n | number\n | React.Component<IPopupProps, IPopupTargetState>\n | React.ComponentClass<Popup>,\n );\n\n return {\n target: newTarget,\n targetRef: nextProps.target,\n };\n }\n\n return prevState;\n }\n\n constructor(props: IPopupProps) {\n super(props);\n this.state = {target: undefined, targetRef: null};\n }\n\n public render(): JSX.Element {\n const props = {...this.props};\n props.style = [styles.rctPopup, this.props.style];\n\n return <RCTPopup {...props} target={this.state.target} />;\n }\n}\n"]}
|
|
@@ -31,6 +31,7 @@ const AndroidHorizontalScrollViewNativeComponent: HostComponent<Props> = NativeC
|
|
|
31
31
|
scrollPerfTag: true,
|
|
32
32
|
sendMomentumEvents: true,
|
|
33
33
|
showsHorizontalScrollIndicator: true,
|
|
34
|
+
snapToAlignment: true,
|
|
34
35
|
snapToEnd: true,
|
|
35
36
|
snapToInterval: true,
|
|
36
37
|
snapToStart: true,
|
|
@@ -346,17 +346,6 @@ type IOSProps = $ReadOnly<{|
|
|
|
346
346
|
* The default value is true.
|
|
347
347
|
*/
|
|
348
348
|
showsHorizontalScrollIndicator?: ?boolean,
|
|
349
|
-
/**
|
|
350
|
-
* When `snapToInterval` is set, `snapToAlignment` will define the relationship
|
|
351
|
-
* of the snapping to the scroll view.
|
|
352
|
-
*
|
|
353
|
-
* - `'start'` (the default) will align the snap at the left (horizontal) or top (vertical)
|
|
354
|
-
* - `'center'` will align the snap in the center
|
|
355
|
-
* - `'end'` will align the snap at the right (horizontal) or bottom (vertical)
|
|
356
|
-
*
|
|
357
|
-
* @platform ios
|
|
358
|
-
*/
|
|
359
|
-
snapToAlignment?: ?('start' | 'center' | 'end'),
|
|
360
349
|
/**
|
|
361
350
|
* The current scale of the scroll view content. The default value is 1.0.
|
|
362
351
|
* @platform ios
|
|
@@ -597,6 +586,15 @@ export type Props = $ReadOnly<{|
|
|
|
597
586
|
* for example when you want your list to have an animated hidable header.
|
|
598
587
|
*/
|
|
599
588
|
StickyHeaderComponent?: StickyHeaderComponentType,
|
|
589
|
+
/**
|
|
590
|
+
* When `snapToInterval` is set, `snapToAlignment` will define the relationship
|
|
591
|
+
* of the snapping to the scroll view.
|
|
592
|
+
*
|
|
593
|
+
* - `'start'` (the default) will align the snap at the left (horizontal) or top (vertical)
|
|
594
|
+
* - `'center'` will align the snap in the center
|
|
595
|
+
* - `'end'` will align the snap at the right (horizontal) or bottom (vertical)
|
|
596
|
+
*/
|
|
597
|
+
snapToAlignment?: ?('start' | 'center' | 'end'),
|
|
600
598
|
/**
|
|
601
599
|
* When set, causes the scroll view to stop at multiples of the value of
|
|
602
600
|
* `snapToInterval`. This can be used for paginating through children
|
|
@@ -1178,11 +1176,6 @@ class ScrollView extends React.Component<Props, State> {
|
|
|
1178
1176
|
);
|
|
1179
1177
|
}
|
|
1180
1178
|
}
|
|
1181
|
-
if (Platform.OS === 'android') {
|
|
1182
|
-
if (this.props.keyboardDismissMode === 'on-drag' && this._isTouching) {
|
|
1183
|
-
dismissKeyboard();
|
|
1184
|
-
}
|
|
1185
|
-
}
|
|
1186
1179
|
this._observedScrollSinceBecomingResponder = true;
|
|
1187
1180
|
this.props.onScroll && this.props.onScroll(e);
|
|
1188
1181
|
};
|
|
@@ -1299,6 +1292,14 @@ class ScrollView extends React.Component<Props, State> {
|
|
|
1299
1292
|
*/
|
|
1300
1293
|
_handleScrollBeginDrag: (e: ScrollEvent) => void = (e: ScrollEvent) => {
|
|
1301
1294
|
FrameRateLogger.beginScroll(); // TODO: track all scrolls after implementing onScrollEndAnimation
|
|
1295
|
+
|
|
1296
|
+
if (
|
|
1297
|
+
Platform.OS === 'android' &&
|
|
1298
|
+
this.props.keyboardDismissMode === 'on-drag'
|
|
1299
|
+
) {
|
|
1300
|
+
dismissKeyboard();
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1302
1303
|
this.props.onScrollBeginDrag && this.props.onScrollBeginDrag(e);
|
|
1303
1304
|
};
|
|
1304
1305
|
|
|
@@ -4,25 +4,29 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
* @flow
|
|
7
|
+
* @flow
|
|
8
8
|
* @format
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
|
|
11
|
+
import AnimatedImplementation from '../../Animated/AnimatedImplementation';
|
|
12
|
+
import AnimatedAddition from '../../Animated/nodes/AnimatedAddition';
|
|
13
|
+
import AnimatedDiffClamp from '../../Animated/nodes/AnimatedDiffClamp';
|
|
14
|
+
import AnimatedNode from '../../Animated/nodes/AnimatedNode';
|
|
15
|
+
|
|
16
16
|
import * as React from 'react';
|
|
17
|
-
import
|
|
17
|
+
import StyleSheet from '../../StyleSheet/StyleSheet';
|
|
18
|
+
import View from '../View/View';
|
|
19
|
+
import Platform from '../../Utilities/Platform';
|
|
20
|
+
|
|
21
|
+
import type {LayoutEvent} from '../../Types/CoreEventTypes';
|
|
18
22
|
|
|
19
|
-
const AnimatedView =
|
|
23
|
+
const AnimatedView = AnimatedImplementation.createAnimatedComponent(View);
|
|
20
24
|
|
|
21
25
|
export type Props = $ReadOnly<{
|
|
22
|
-
children?: React.Element
|
|
26
|
+
children?: React.Element<any>,
|
|
23
27
|
nextHeaderLayoutY: ?number,
|
|
24
28
|
onLayout: (event: LayoutEvent) => void,
|
|
25
|
-
scrollAnimatedValue:
|
|
29
|
+
scrollAnimatedValue: AnimatedImplementation.Value,
|
|
26
30
|
// Will cause sticky headers to stick at the bottom of the ScrollView instead
|
|
27
31
|
// of the top.
|
|
28
32
|
inverted: ?boolean,
|
|
@@ -32,275 +36,287 @@ export type Props = $ReadOnly<{
|
|
|
32
36
|
hiddenOnScroll?: ?boolean,
|
|
33
37
|
}>;
|
|
34
38
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
inverted,
|
|
44
|
-
scrollViewHeight,
|
|
45
|
-
hiddenOnScroll,
|
|
46
|
-
scrollAnimatedValue,
|
|
47
|
-
nextHeaderLayoutY: _nextHeaderLayoutY,
|
|
48
|
-
} = props;
|
|
39
|
+
type State = {
|
|
40
|
+
measured: boolean,
|
|
41
|
+
layoutY: number,
|
|
42
|
+
layoutHeight: number,
|
|
43
|
+
nextHeaderLayoutY: ?number,
|
|
44
|
+
translateY: ?number,
|
|
45
|
+
...
|
|
46
|
+
};
|
|
49
47
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
48
|
+
class ScrollViewStickyHeader extends React.Component<Props, State> {
|
|
49
|
+
state: State = {
|
|
50
|
+
measured: false,
|
|
51
|
+
layoutY: 0,
|
|
52
|
+
layoutHeight: 0,
|
|
53
|
+
nextHeaderLayoutY: this.props.nextHeaderLayoutY,
|
|
54
|
+
translateY: null,
|
|
55
|
+
};
|
|
58
56
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
componentRef.current = ref;
|
|
64
|
-
if (ref) {
|
|
65
|
-
ref.setNextHeaderY = value => {
|
|
66
|
-
setNextHeaderLayoutY(value);
|
|
67
|
-
};
|
|
68
|
-
setIsFabric(
|
|
69
|
-
!!(
|
|
70
|
-
// An internal transform mangles variables with leading "_" as private.
|
|
71
|
-
// eslint-disable-next-line dot-notation
|
|
72
|
-
ref['_internalInstanceHandle']?.stateNode?.canonical
|
|
73
|
-
),
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
|
-
},
|
|
77
|
-
});
|
|
57
|
+
_translateY: ?AnimatedNode = null;
|
|
58
|
+
_shouldRecreateTranslateY: boolean = true;
|
|
59
|
+
_haveReceivedInitialZeroTranslateY: boolean = true;
|
|
60
|
+
_ref: any; // TODO T53738161: flow type this, and the whole file
|
|
78
61
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
.interpolate({
|
|
85
|
-
extrapolateLeft: 'clamp',
|
|
86
|
-
inputRange: [layoutY, layoutY + 1],
|
|
87
|
-
outputRange: ([0, 1]: Array<number>),
|
|
88
|
-
})
|
|
89
|
-
.interpolate({
|
|
90
|
-
inputRange: [0, 1],
|
|
91
|
-
outputRange: ([0, -1]: Array<number>),
|
|
92
|
-
}),
|
|
93
|
-
-layoutHeight,
|
|
94
|
-
0,
|
|
95
|
-
)
|
|
96
|
-
: null,
|
|
97
|
-
[scrollAnimatedValue, layoutHeight, layoutY, hiddenOnScroll],
|
|
98
|
-
);
|
|
62
|
+
// Fabric-only:
|
|
63
|
+
_timer: ?TimeoutID;
|
|
64
|
+
_animatedValueListenerId: string;
|
|
65
|
+
_animatedValueListener: (valueObject: $ReadOnly<{|value: number|}>) => void;
|
|
66
|
+
_debounceTimeout: number = Platform.OS === 'android' ? 15 : 64;
|
|
99
67
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const inputRange: Array<number> = [-1, 0];
|
|
105
|
-
const outputRange: Array<number> = [0, 0];
|
|
106
|
-
const initialTranslateY: Animated.Interpolation = scrollAnimatedValue.interpolate(
|
|
107
|
-
{
|
|
108
|
-
inputRange,
|
|
109
|
-
outputRange,
|
|
110
|
-
},
|
|
111
|
-
);
|
|
68
|
+
setNextHeaderY: (y: number) => void = (y: number): void => {
|
|
69
|
+
this._shouldRecreateTranslateY = true;
|
|
70
|
+
this.setState({nextHeaderLayoutY: y});
|
|
71
|
+
};
|
|
112
72
|
|
|
113
|
-
|
|
114
|
-
|
|
73
|
+
componentWillUnmount() {
|
|
74
|
+
if (this._translateY != null && this._animatedValueListenerId != null) {
|
|
75
|
+
this._translateY.removeListener(this._animatedValueListenerId);
|
|
76
|
+
}
|
|
77
|
+
if (this._timer) {
|
|
78
|
+
clearTimeout(this._timer);
|
|
115
79
|
}
|
|
116
|
-
|
|
117
|
-
});
|
|
80
|
+
}
|
|
118
81
|
|
|
119
|
-
|
|
120
|
-
|
|
82
|
+
UNSAFE_componentWillReceiveProps(nextProps: Props) {
|
|
83
|
+
if (
|
|
84
|
+
nextProps.scrollViewHeight !== this.props.scrollViewHeight ||
|
|
85
|
+
nextProps.scrollAnimatedValue !== this.props.scrollAnimatedValue ||
|
|
86
|
+
nextProps.inverted !== this.props.inverted
|
|
87
|
+
) {
|
|
88
|
+
this._shouldRecreateTranslateY = true;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
121
91
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
92
|
+
updateTranslateListener(
|
|
93
|
+
translateY: AnimatedImplementation.Interpolation,
|
|
94
|
+
isFabric: boolean,
|
|
95
|
+
offset: AnimatedDiffClamp | null,
|
|
96
|
+
) {
|
|
97
|
+
if (this._translateY != null && this._animatedValueListenerId != null) {
|
|
98
|
+
this._translateY.removeListener(this._animatedValueListenerId);
|
|
125
99
|
}
|
|
126
|
-
|
|
100
|
+
offset
|
|
101
|
+
? (this._translateY = new AnimatedAddition(translateY, offset))
|
|
102
|
+
: (this._translateY = translateY);
|
|
127
103
|
|
|
128
|
-
|
|
129
|
-
// updates, which is several times per frame during scrolling.
|
|
130
|
-
// To ensure that the Fabric ShadowTree has the most recent
|
|
131
|
-
// translate style of this node, we debounce the value and then
|
|
132
|
-
// pass it through to the underlying node during render.
|
|
133
|
-
// This is:
|
|
134
|
-
// 1. Only an issue in Fabric.
|
|
135
|
-
// 2. Worse in Android than iOS. In Android, but not iOS, you
|
|
136
|
-
// can touch and move your finger slightly and still trigger
|
|
137
|
-
// a "tap" event. In iOS, moving will cancel the tap in
|
|
138
|
-
// both Fabric and non-Fabric. On Android when you move
|
|
139
|
-
// your finger, the hit-detection moves from the Android
|
|
140
|
-
// platform to JS, so we need the ShadowTree to have knowledge
|
|
141
|
-
// of the current position.
|
|
142
|
-
const animatedValueListener = useCallback(
|
|
143
|
-
({value}) => {
|
|
144
|
-
const _debounceTimeout: number = Platform.OS === 'android' ? 15 : 64;
|
|
145
|
-
// When the AnimatedInterpolation is recreated, it always initializes
|
|
146
|
-
// to a value of zero and emits a value change of 0 to its listeners.
|
|
147
|
-
if (value === 0 && !_haveReceivedInitialZeroTranslateY.current) {
|
|
148
|
-
_haveReceivedInitialZeroTranslateY.current = true;
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
if (_timer.current != null) {
|
|
152
|
-
clearTimeout(_timer.current);
|
|
153
|
-
}
|
|
154
|
-
_timer.current = setTimeout(() => {
|
|
155
|
-
if (value !== translateY) {
|
|
156
|
-
setTranslateY(value);
|
|
157
|
-
}
|
|
158
|
-
}, _debounceTimeout);
|
|
159
|
-
},
|
|
160
|
-
[translateY],
|
|
161
|
-
);
|
|
104
|
+
this._shouldRecreateTranslateY = false;
|
|
162
105
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
106
|
+
if (!isFabric) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
166
109
|
|
|
167
|
-
if (
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
inputRange.push(stickStartPoint + 1);
|
|
189
|
-
outputRange.push(1);
|
|
190
|
-
// If the next sticky header has not loaded yet (probably windowing) or is the last
|
|
191
|
-
// we can just keep it sticked forever.
|
|
192
|
-
const collisionPoint =
|
|
193
|
-
(nextHeaderLayoutY || 0) - layoutHeight - scrollViewHeight;
|
|
194
|
-
if (collisionPoint > stickStartPoint) {
|
|
195
|
-
inputRange.push(collisionPoint, collisionPoint + 1);
|
|
196
|
-
outputRange.push(
|
|
197
|
-
collisionPoint - stickStartPoint,
|
|
198
|
-
collisionPoint - stickStartPoint,
|
|
199
|
-
);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
110
|
+
if (!this._animatedValueListener) {
|
|
111
|
+
// This is called whenever the (Interpolated) Animated Value
|
|
112
|
+
// updates, which is several times per frame during scrolling.
|
|
113
|
+
// To ensure that the Fabric ShadowTree has the most recent
|
|
114
|
+
// translate style of this node, we debounce the value and then
|
|
115
|
+
// pass it through to the underlying node during render.
|
|
116
|
+
// This is:
|
|
117
|
+
// 1. Only an issue in Fabric.
|
|
118
|
+
// 2. Worse in Android than iOS. In Android, but not iOS, you
|
|
119
|
+
// can touch and move your finger slightly and still trigger
|
|
120
|
+
// a "tap" event. In iOS, moving will cancel the tap in
|
|
121
|
+
// both Fabric and non-Fabric. On Android when you move
|
|
122
|
+
// your finger, the hit-detection moves from the Android
|
|
123
|
+
// platform to JS, so we need the ShadowTree to have knowledge
|
|
124
|
+
// of the current position.
|
|
125
|
+
this._animatedValueListener = ({value}) => {
|
|
126
|
+
// When the AnimatedInterpolation is recreated, it always initializes
|
|
127
|
+
// to a value of zero and emits a value change of 0 to its listeners.
|
|
128
|
+
if (value === 0 && !this._haveReceivedInitialZeroTranslateY) {
|
|
129
|
+
this._haveReceivedInitialZeroTranslateY = true;
|
|
130
|
+
return;
|
|
202
131
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
// - Negative scroll: no translation
|
|
206
|
-
// - From 0 to the y of the header: no translation. This will cause the header
|
|
207
|
-
// to scroll normally until it reaches the top of the scroll view.
|
|
208
|
-
// - From header y to when the next header y hits the bottom edge of the header: translate
|
|
209
|
-
// equally to scroll. This will cause the header to stay at the top of the scroll view.
|
|
210
|
-
// - Past the collision with the next header y: no more translation. This will cause the
|
|
211
|
-
// header to continue scrolling up and make room for the next sticky header.
|
|
212
|
-
// In the case that there is no next header just translate equally to
|
|
213
|
-
// scroll indefinitely.
|
|
214
|
-
inputRange.push(layoutY);
|
|
215
|
-
outputRange.push(0);
|
|
216
|
-
// If the next sticky header has not loaded yet (probably windowing) or is the last
|
|
217
|
-
// we can just keep it sticked forever.
|
|
218
|
-
const collisionPoint = (nextHeaderLayoutY || 0) - layoutHeight;
|
|
219
|
-
if (collisionPoint >= layoutY) {
|
|
220
|
-
inputRange.push(collisionPoint, collisionPoint + 1);
|
|
221
|
-
outputRange.push(collisionPoint - layoutY, collisionPoint - layoutY);
|
|
222
|
-
} else {
|
|
223
|
-
inputRange.push(layoutY + 1);
|
|
224
|
-
outputRange.push(1);
|
|
132
|
+
if (this._timer) {
|
|
133
|
+
clearTimeout(this._timer);
|
|
225
134
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
if (offset != null) {
|
|
235
|
-
newAnimatedTranslateY = Animated.add(newAnimatedTranslateY, offset);
|
|
135
|
+
this._timer = setTimeout(() => {
|
|
136
|
+
if (value !== this.state.translateY) {
|
|
137
|
+
this.setState({
|
|
138
|
+
translateY: value,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}, this._debounceTimeout);
|
|
142
|
+
};
|
|
236
143
|
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
let animatedListenerId;
|
|
240
|
-
if (isFabric) {
|
|
241
|
-
animatedListenerId = newAnimatedTranslateY.addListener(
|
|
242
|
-
animatedValueListener,
|
|
243
|
-
);
|
|
144
|
+
if (this.state.translateY !== 0 && this.state.translateY != null) {
|
|
145
|
+
this._haveReceivedInitialZeroTranslateY = false;
|
|
244
146
|
}
|
|
147
|
+
this._animatedValueListenerId = translateY.addListener(
|
|
148
|
+
this._animatedValueListener,
|
|
149
|
+
);
|
|
150
|
+
}
|
|
245
151
|
|
|
246
|
-
|
|
152
|
+
_onLayout = event => {
|
|
153
|
+
const layoutY = event.nativeEvent.layout.y;
|
|
154
|
+
const layoutHeight = event.nativeEvent.layout.height;
|
|
155
|
+
const measured = true;
|
|
247
156
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
}
|
|
256
|
-
};
|
|
257
|
-
}, [nextHeaderLayoutY, measured, layoutHeight, layoutY, scrollViewHeight, scrollAnimatedValue, inverted, offset, animatedValueListener, isFabric]);
|
|
157
|
+
if (
|
|
158
|
+
layoutY !== this.state.layoutY ||
|
|
159
|
+
layoutHeight !== this.state.layoutHeight ||
|
|
160
|
+
measured !== this.state.measured
|
|
161
|
+
) {
|
|
162
|
+
this._shouldRecreateTranslateY = true;
|
|
163
|
+
}
|
|
258
164
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
165
|
+
this.setState({
|
|
166
|
+
measured,
|
|
167
|
+
layoutY,
|
|
168
|
+
layoutHeight,
|
|
169
|
+
});
|
|
263
170
|
|
|
264
|
-
props.onLayout(event);
|
|
265
|
-
const child = React.Children.only(props.children);
|
|
171
|
+
this.props.onLayout(event);
|
|
172
|
+
const child = React.Children.only(this.props.children);
|
|
266
173
|
if (child.props.onLayout) {
|
|
267
174
|
child.props.onLayout(event);
|
|
268
175
|
}
|
|
269
176
|
};
|
|
270
177
|
|
|
271
|
-
|
|
178
|
+
_setComponentRef = ref => {
|
|
179
|
+
this._ref = ref;
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
render(): React.Node {
|
|
183
|
+
// Fabric Detection
|
|
184
|
+
const isFabric = !!(
|
|
185
|
+
// An internal transform mangles variables with leading "_" as private.
|
|
186
|
+
// eslint-disable-next-line dot-notation
|
|
187
|
+
(this._ref && this._ref['_internalInstanceHandle']?.stateNode?.canonical)
|
|
188
|
+
);
|
|
189
|
+
// Initially and in the case of updated props or layout, we
|
|
190
|
+
// recreate this interpolated value. Otherwise, we do not recreate
|
|
191
|
+
// when there are state changes.
|
|
192
|
+
if (this._shouldRecreateTranslateY) {
|
|
193
|
+
const {inverted, scrollViewHeight} = this.props;
|
|
194
|
+
const {measured, layoutHeight, layoutY, nextHeaderLayoutY} = this.state;
|
|
195
|
+
const inputRange: Array<number> = [-1, 0];
|
|
196
|
+
const outputRange: Array<number> = [0, 0];
|
|
272
197
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
198
|
+
if (measured) {
|
|
199
|
+
if (inverted) {
|
|
200
|
+
// The interpolation looks like:
|
|
201
|
+
// - Negative scroll: no translation
|
|
202
|
+
// - `stickStartPoint` is the point at which the header will start sticking.
|
|
203
|
+
// It is calculated using the ScrollView viewport height so it is a the bottom.
|
|
204
|
+
// - Headers that are in the initial viewport will never stick, `stickStartPoint`
|
|
205
|
+
// will be negative.
|
|
206
|
+
// - From 0 to `stickStartPoint` no translation. This will cause the header
|
|
207
|
+
// to scroll normally until it reaches the top of the scroll view.
|
|
208
|
+
// - From `stickStartPoint` to when the next header y hits the bottom edge of the header: translate
|
|
209
|
+
// equally to scroll. This will cause the header to stay at the top of the scroll view.
|
|
210
|
+
// - Past the collision with the next header y: no more translation. This will cause the
|
|
211
|
+
// header to continue scrolling up and make room for the next sticky header.
|
|
212
|
+
// In the case that there is no next header just translate equally to
|
|
213
|
+
// scroll indefinitely.
|
|
214
|
+
if (scrollViewHeight != null) {
|
|
215
|
+
const stickStartPoint = layoutY + layoutHeight - scrollViewHeight;
|
|
216
|
+
if (stickStartPoint > 0) {
|
|
217
|
+
inputRange.push(stickStartPoint);
|
|
218
|
+
outputRange.push(0);
|
|
219
|
+
inputRange.push(stickStartPoint + 1);
|
|
220
|
+
outputRange.push(1);
|
|
221
|
+
// If the next sticky header has not loaded yet (probably windowing) or is the last
|
|
222
|
+
// we can just keep it sticked forever.
|
|
223
|
+
const collisionPoint =
|
|
224
|
+
(nextHeaderLayoutY || 0) - layoutHeight - scrollViewHeight;
|
|
225
|
+
if (collisionPoint > stickStartPoint) {
|
|
226
|
+
inputRange.push(collisionPoint, collisionPoint + 1);
|
|
227
|
+
outputRange.push(
|
|
228
|
+
collisionPoint - stickStartPoint,
|
|
229
|
+
collisionPoint - stickStartPoint,
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
} else {
|
|
235
|
+
// The interpolation looks like:
|
|
236
|
+
// - Negative scroll: no translation
|
|
237
|
+
// - From 0 to the y of the header: no translation. This will cause the header
|
|
238
|
+
// to scroll normally until it reaches the top of the scroll view.
|
|
239
|
+
// - From header y to when the next header y hits the bottom edge of the header: translate
|
|
240
|
+
// equally to scroll. This will cause the header to stay at the top of the scroll view.
|
|
241
|
+
// - Past the collision with the next header y: no more translation. This will cause the
|
|
242
|
+
// header to continue scrolling up and make room for the next sticky header.
|
|
243
|
+
// In the case that there is no next header just translate equally to
|
|
244
|
+
// scroll indefinitely.
|
|
245
|
+
inputRange.push(layoutY);
|
|
246
|
+
outputRange.push(0);
|
|
247
|
+
// If the next sticky header has not loaded yet (probably windowing) or is the last
|
|
248
|
+
// we can just keep it sticked forever.
|
|
249
|
+
const collisionPoint = (nextHeaderLayoutY || 0) - layoutHeight;
|
|
250
|
+
if (collisionPoint >= layoutY) {
|
|
251
|
+
inputRange.push(collisionPoint, collisionPoint + 1);
|
|
252
|
+
outputRange.push(
|
|
253
|
+
collisionPoint - layoutY,
|
|
254
|
+
collisionPoint - layoutY,
|
|
255
|
+
);
|
|
256
|
+
} else {
|
|
257
|
+
inputRange.push(layoutY + 1);
|
|
258
|
+
outputRange.push(1);
|
|
259
|
+
}
|
|
278
260
|
}
|
|
279
|
-
|
|
261
|
+
}
|
|
280
262
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
263
|
+
this.updateTranslateListener(
|
|
264
|
+
this.props.scrollAnimatedValue.interpolate({
|
|
265
|
+
inputRange,
|
|
266
|
+
outputRange,
|
|
267
|
+
}),
|
|
268
|
+
isFabric,
|
|
269
|
+
this.props.hiddenOnScroll
|
|
270
|
+
? new AnimatedDiffClamp(
|
|
271
|
+
this.props.scrollAnimatedValue
|
|
272
|
+
.interpolate({
|
|
273
|
+
extrapolateLeft: 'clamp',
|
|
274
|
+
inputRange: [layoutY, layoutY + 1],
|
|
275
|
+
outputRange: ([0, 1]: Array<number>),
|
|
276
|
+
})
|
|
277
|
+
.interpolate({
|
|
278
|
+
inputRange: [0, 1],
|
|
279
|
+
outputRange: ([0, -1]: Array<number>),
|
|
280
|
+
}),
|
|
281
|
+
-this.state.layoutHeight,
|
|
282
|
+
0,
|
|
283
|
+
)
|
|
284
|
+
: null,
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const child = React.Children.only(this.props.children);
|
|
289
|
+
|
|
290
|
+
// TODO T68319535: remove this if NativeAnimated is rewritten for Fabric
|
|
291
|
+
const passthroughAnimatedPropExplicitValues =
|
|
292
|
+
isFabric && this.state.translateY != null
|
|
293
|
+
? {
|
|
294
|
+
style: {transform: [{translateY: this.state.translateY}]},
|
|
295
|
+
}
|
|
296
|
+
: null;
|
|
297
|
+
|
|
298
|
+
return (
|
|
299
|
+
<AnimatedView
|
|
300
|
+
collapsable={false}
|
|
301
|
+
nativeID={this.props.nativeID}
|
|
302
|
+
onLayout={this._onLayout}
|
|
303
|
+
ref={this._setComponentRef}
|
|
304
|
+
style={[
|
|
305
|
+
child.props.style,
|
|
306
|
+
styles.header,
|
|
307
|
+
{transform: [{translateY: this._translateY}]},
|
|
308
|
+
]}
|
|
309
|
+
passthroughAnimatedPropExplicitValues={
|
|
310
|
+
passthroughAnimatedPropExplicitValues
|
|
311
|
+
}>
|
|
312
|
+
{React.cloneElement(child, {
|
|
313
|
+
style: styles.fill, // We transfer the child style to the wrapper.
|
|
314
|
+
onLayout: undefined, // we call this manually through our this._onLayout
|
|
315
|
+
})}
|
|
316
|
+
</AnimatedView>
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
304
320
|
|
|
305
321
|
const styles = StyleSheet.create({
|
|
306
322
|
header: {
|
|
@@ -312,4 +328,4 @@ const styles = StyleSheet.create({
|
|
|
312
328
|
},
|
|
313
329
|
});
|
|
314
330
|
|
|
315
|
-
|
|
331
|
+
module.exports = ScrollViewStickyHeader;
|