Skip to content

Commit cc9e4cd

Browse files
author
Pierre Poupin
authored
feat(scrollview)!: add CSS scroll on ScrollView (#146)
* refactor(scrollview): move scrollview to its own directory * refactor(scrollview): extract pointer logic out of ScrollView * feat(ScrollView): add CSS scrolling for scroll view * chore(example): remove align self stretch from box * chore(example): allow to pass style to box * refactor(scrollview): split into subdirectories * test(scrollview): add test for custom scroll view * chore(example): use css scroll everywhere * feat(scrollview)!: make css the default scrollview * docs(scrollview): add doc
1 parent db85ef8 commit cc9e4cd

17 files changed

Lines changed: 824 additions & 281 deletions

docs/api.md

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -132,17 +132,18 @@ It also ensures that the scroll event is propagated properly for parent ScrollVi
132132

133133
The `SpatialNavigationScrollView` component receives the following props:
134134

135-
| Name | Type | Default | Description |
136-
| ------------------------------- | -------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
137-
| `horizontal` | `boolean` | `false` | Determines if the scrolling orientation is horizontal. If `false`, the scrolling orientation will be vertical. |
138-
| `offsetFromStart` | `number` | `0` | This offset is used to prevent the element from sticking too closely to the edges of the screen during scrolling. This is a margin in pixels. |
139-
| `style` | `ViewStyle` | `null` | Style for the ScrollView. This can be any valid React Native style object. |
140-
| `children` | `ReactNode` | `null` | Child elements of the component. They are expected to be one or multiple `SpatialNavigationNode` elements. |
141-
| `ascendingArrow` | `ReactElement` | `null` | For web TVs cursor handling. Optional component to display as the arrow to scroll on the ascending order. |
142-
| `ascendingArrowContainerStyle` | `ViewStyle` | `null` | For web TVs cursor handling. Style of the view which wraps the ascending arrow. Hover this view will trigger the scroll. |
143-
| `descendingArrow` | `ReactElement` | `null` | For web TVs cursor handling. Optional component to display as the arrow to scroll on the descending order. |
144-
| `descendingArrowContainerStyle` | `ViewStyle` | `null` | For web TVs cursor handling. Style of the view which wraps the descending arrow. Hover this view will trigger the scroll. |
145-
| `pointerScrollSpeed` | `number` | `10` | For web TVs cursor handling. Speed of the pointer scroll. It represents the number of pixels scrolled every 10ms when hovering a scroll arrow with a pointer. |
135+
| Name | Type | Default | Description |
136+
| ------------------------------- | -------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
137+
| `horizontal` | `boolean` | `false` | Determines if the scrolling orientation is horizontal. If `false`, the scrolling orientation will be vertical. |
138+
| `offsetFromStart` | `number` | `0` | This offset is used to prevent the element from sticking too closely to the edges of the screen during scrolling. This is a margin in pixels. |
139+
| `style` | `ViewStyle` | `null` | Style for the ScrollView. This can be any valid React Native style object. |
140+
| `children` | `ReactNode` | `null` | Child elements of the component. They are expected to be one or multiple `SpatialNavigationNode` elements. |
141+
| `ascendingArrow` | `ReactElement` | `null` | For web TVs cursor handling. Optional component to display as the arrow to scroll on the ascending order. |
142+
| `ascendingArrowContainerStyle` | `ViewStyle` | `null` | For web TVs cursor handling. Style of the view which wraps the ascending arrow. Hover this view will trigger the scroll. |
143+
| `descendingArrow` | `ReactElement` | `null` | For web TVs cursor handling. Optional component to display as the arrow to scroll on the descending order. |
144+
| `descendingArrowContainerStyle` | `ViewStyle` | `null` | For web TVs cursor handling. Style of the view which wraps the descending arrow. Hover this view will trigger the scroll. |
145+
| `pointerScrollSpeed` | `number` | `10` | For web TVs cursor handling. Speed of the pointer scroll. It represents the number of pixels scrolled every 10ms when hovering a scroll arrow with a pointer. |
146+
| `useNativeScroll` | `boolean` | `false` | Not recommended. Setting this to true disables the use of CSS scroll. It will scroll using the native ScrollView from React Native. CSS scrolling should be snappier and smoother. |
146147

147148
## Usage
148149

@@ -153,7 +154,7 @@ const FocusableNode = () => (
153154
</SpatialNavigationNode>
154155
);
155156

156-
<SpatialNavigationScrollView horizontal={true} style={{ padding: 20 }} offsetFromStart={10}>
157+
<SpatialNavigationScrollView horizontal style={{ padding: 20 }} offsetFromStart={10}>
157158
<FocusableNode />
158159
<FocusableNode />
159160
<FocusableNode />

packages/example/src/design-system/components/Box.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ interface Props {
2222
paddingTop?: keyof Theme['spacings'];
2323
padding?: keyof Theme['spacings'];
2424
testID?: string;
25+
style?: ViewStyle;
2526
children: ReactNode;
2627
}
2728

@@ -64,6 +65,5 @@ const StyledView = styled(View, {
6465
paddingLeft: paddingLeft && theme.spacings[paddingLeft],
6566
paddingTop: paddingTop && theme.spacings[paddingTop],
6667
padding: padding && theme.spacings[padding],
67-
alignSelf: 'stretch',
6868
}),
6969
);

packages/example/src/pages/GridWithLongNodesPage.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export const GridWithLongNodesPage = () => {
3232
<CenteringView>
3333
<GridContainer>
3434
<SpatialNavigationScrollView
35+
useCssScroll
3536
offsetFromStart={HEADER_SIZE + 20}
3637
ascendingArrow={<BottomArrow />}
3738
ascendingArrowContainerStyle={styles.bottomArrowContainer}

packages/lib/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { configureRemoteControl } from './spatial-navigation/configureRemoteCont
22
export { Directions } from '@bam.tech/lrud';
33
export { SpatialNavigationNode } from './spatial-navigation/components/Node';
44
export { SpatialNavigationRoot } from './spatial-navigation/components/Root';
5-
export { SpatialNavigationScrollView } from './spatial-navigation/components/ScrollView';
5+
export { SpatialNavigationScrollView } from './spatial-navigation/components/ScrollView/ScrollView';
66
export { SpatialNavigationView } from './spatial-navigation/components/View';
77
export { DefaultFocus } from './spatial-navigation/context/DefaultFocusContext';
88
export { SpatialNavigationVirtualizedList } from './spatial-navigation/components/virtualizedList/SpatialNavigationVirtualizedList';

packages/lib/src/spatial-navigation/components/ScrollView.tsx

Lines changed: 0 additions & 263 deletions
This file was deleted.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import React from 'react';
2+
import { ViewStyle, ScrollView } from 'react-native';
3+
import { CustomScrollView } from './CustomScrollView/CustomScrollView';
4+
import { CustomScrollViewRef } from './types';
5+
6+
type Props = {
7+
useNativeScroll: boolean;
8+
9+
horizontal?: boolean;
10+
children: React.ReactNode;
11+
style?: ViewStyle;
12+
contentContainerStyle?: ViewStyle;
13+
scrollDuration?: number;
14+
onScroll?: (event: { nativeEvent: { contentOffset: { y: number; x: number } } }) => void;
15+
testID?: string;
16+
};
17+
18+
export const AnyScrollView = React.forwardRef<CustomScrollViewRef, Props>(
19+
({ useNativeScroll, ...props }: Props, ref) => {
20+
if (useNativeScroll) {
21+
return (
22+
<ScrollView
23+
ref={ref as React.RefObject<ScrollView>}
24+
showsHorizontalScrollIndicator={false}
25+
showsVerticalScrollIndicator={false}
26+
scrollEnabled={false}
27+
scrollEventThrottle={16}
28+
{...props}
29+
/>
30+
);
31+
}
32+
33+
return <CustomScrollView ref={ref} {...props} />;
34+
},
35+
);
36+
37+
AnyScrollView.displayName = 'AnyScrollView';

0 commit comments

Comments
 (0)