diff --git a/README.md b/README.md
index 440a9dbe..1bb83219 100644
--- a/README.md
+++ b/README.md
@@ -140,7 +140,7 @@ React Native v0.55
| Picker | ✓ | |
| RefreshControl | ✘ | Not started ([#1027](https://github.com/necolas/react-native-web/issues/1027)). |
| SafeAreaView | ✓ | |
-| ScrollView | ✓ | Missing momentum scroll events ([#1021](https://github.com/necolas/react-native-web/issues/1021)) and `pagingEnabled` ([#1057](https://github.com/necolas/react-native-web/issues/1057)). |
+| ScrollView | ✓ | Missing momentum scroll events ([#1021](https://github.com/necolas/react-native-web/issues/1021)). |
| SectionList | ✓ | |
| Slider | ✘ | Not started ([#1022](https://github.com/necolas/react-native-web/issues/1022)). |
| StatusBar | (✓) | Mock. No equivalent web APIs. |
diff --git a/packages/react-native-web/src/exports/ScrollView/__tests__/__snapshots__/index-test.js.snap b/packages/react-native-web/src/exports/ScrollView/__tests__/__snapshots__/index-test.js.snap
new file mode 100644
index 00000000..61e5bbe8
--- /dev/null
+++ b/packages/react-native-web/src/exports/ScrollView/__tests__/__snapshots__/index-test.js.snap
@@ -0,0 +1,7 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/ScrollView "pagingEnabled" prop 1`] = `undefined`;
+
+exports[`components/ScrollView "pagingEnabled" prop 2`] = `"y mandatory"`;
+
+exports[`components/ScrollView "pagingEnabled" prop 3`] = `"start"`;
diff --git a/packages/react-native-web/src/exports/ScrollView/__tests__/index-test.js b/packages/react-native-web/src/exports/ScrollView/__tests__/index-test.js
index 72d506c0..76c388c2 100644
--- a/packages/react-native-web/src/exports/ScrollView/__tests__/index-test.js
+++ b/packages/react-native-web/src/exports/ScrollView/__tests__/index-test.js
@@ -2,7 +2,8 @@
import React from 'react';
import ScrollView from '..';
-import { mount } from 'enzyme';
+import StyleSheet from '../../StyleSheet';
+import { mount, shallow } from 'enzyme';
describe('components/ScrollView', () => {
test('instance method setNativeProps', () => {
@@ -11,4 +12,17 @@ describe('components/ScrollView', () => {
instance.setNativeProps();
}).not.toThrow();
});
+
+ test('"pagingEnabled" prop', () => {
+ const getStyleProp = (component, prop) => StyleSheet.flatten(component.prop('style'))[prop];
+
+ // false
+ const component = shallow();
+ expect(getStyleProp(component, 'scrollSnapType')).toMatchSnapshot();
+
+ // true
+ component.setProps({ pagingEnabled: true });
+ expect(getStyleProp(component, 'scrollSnapType')).toMatchSnapshot();
+ expect(getStyleProp(component.children().childAt(0), 'scrollSnapAlign')).toMatchSnapshot();
+ });
});
diff --git a/packages/react-native-web/src/exports/ScrollView/index.js b/packages/react-native-web/src/exports/ScrollView/index.js
index 4574b2dd..7fa8bea5 100644
--- a/packages/react-native-web/src/exports/ScrollView/index.js
+++ b/packages/react-native-web/src/exports/ScrollView/index.js
@@ -137,10 +137,10 @@ const ScrollView = createReactClass({
onContentSizeChange,
refreshControl,
stickyHeaderIndices,
+ pagingEnabled,
/* eslint-disable */
keyboardDismissMode,
onScroll,
- pagingEnabled,
/* eslint-enable */
...other
} = this.props;
@@ -164,11 +164,24 @@ const ScrollView = createReactClass({
};
}
+ const hasStickyHeaderIndices = !horizontal && Array.isArray(stickyHeaderIndices);
const children =
- !horizontal && Array.isArray(stickyHeaderIndices)
+ hasStickyHeaderIndices || pagingEnabled
? React.Children.map(this.props.children, (child, i) => {
- if (child && stickyHeaderIndices.indexOf(i) > -1) {
- return {child};
+ if (child != null) {
+ const isSticky = hasStickyHeaderIndices && stickyHeaderIndices.indexOf(i) > -1;
+ if (isSticky || pagingEnabled) {
+ return (
+
+ {child}
+
+ );
+ }
} else {
return child;
}
@@ -181,15 +194,21 @@ const ScrollView = createReactClass({
children={children}
collapsable={false}
ref={this._setInnerViewRef}
- style={[horizontal && styles.contentContainerHorizontal, contentContainerStyle]}
+ style={StyleSheet.compose(
+ horizontal && styles.contentContainerHorizontal,
+ contentContainerStyle
+ )}
/>
);
const baseStyle = horizontal ? styles.baseHorizontal : styles.baseVertical;
+ const pagingEnabledStyle = horizontal
+ ? styles.pagingEnabledHorizontal
+ : styles.pagingEnabledVertical;
const props = {
...other,
- style: [baseStyle, this.props.style],
+ style: [baseStyle, pagingEnabled && pagingEnabledStyle, this.props.style],
onTouchStart: this.scrollResponderHandleTouchStart,
onTouchMove: this.scrollResponderHandleTouchMove,
onTouchEnd: this.scrollResponderHandleTouchEnd,
@@ -223,7 +242,7 @@ const ScrollView = createReactClass({
}
return (
-
+
{contentContainer}
);
@@ -294,6 +313,15 @@ const styles = StyleSheet.create({
position: 'sticky',
top: 0,
zIndex: 10
+ },
+ pagingEnabledHorizontal: {
+ scrollSnapType: 'x mandatory'
+ },
+ pagingEnabledVertical: {
+ scrollSnapType: 'y mandatory'
+ },
+ pagingEnabledChild: {
+ scrollSnapAlign: 'start'
}
});
diff --git a/packages/react-native-web/src/exports/View/ViewStylePropTypes.js b/packages/react-native-web/src/exports/View/ViewStylePropTypes.js
index 308ebaae..bf07b1de 100644
--- a/packages/react-native-web/src/exports/View/ViewStylePropTypes.js
+++ b/packages/react-native-web/src/exports/View/ViewStylePropTypes.js
@@ -51,6 +51,8 @@ const ViewStylePropTypes = {
overscrollBehavior: overscrollBehaviorType,
overscrollBehaviorX: overscrollBehaviorType,
overscrollBehaviorY: overscrollBehaviorType,
+ scrollSnapAlign: string,
+ scrollSnapType: string,
WebkitMaskImage: string,
WebkitOverflowScrolling: oneOf(['auto', 'touch'])
};
diff --git a/packages/website/storybook/1-components/ScrollView/ScrollViewScreen.js b/packages/website/storybook/1-components/ScrollView/ScrollViewScreen.js
index dbf2a923..92e2893e 100644
--- a/packages/website/storybook/1-components/ScrollView/ScrollViewScreen.js
+++ b/packages/website/storybook/1-components/ScrollView/ScrollViewScreen.js
@@ -101,6 +101,12 @@ const ScrollViewScreen = () => (
]}
/>
+
+