Skip to content

Commit

Permalink
feat(scrollview)!: add CSS scroll on ScrollView (#146)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
pierpo authored Aug 1, 2024
1 parent db85ef8 commit cc9e4cd
Show file tree
Hide file tree
Showing 17 changed files with 824 additions and 281 deletions.
25 changes: 13 additions & 12 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,17 +132,18 @@ It also ensures that the scroll event is propagated properly for parent ScrollVi

The `SpatialNavigationScrollView` component receives the following props:

| Name | Type | Default | Description |
| ------------------------------- | -------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `horizontal` | `boolean` | `false` | Determines if the scrolling orientation is horizontal. If `false`, the scrolling orientation will be vertical. |
| `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. |
| `style` | `ViewStyle` | `null` | Style for the ScrollView. This can be any valid React Native style object. |
| `children` | `ReactNode` | `null` | Child elements of the component. They are expected to be one or multiple `SpatialNavigationNode` elements. |
| `ascendingArrow` | `ReactElement` | `null` | For web TVs cursor handling. Optional component to display as the arrow to scroll on the ascending order. |
| `ascendingArrowContainerStyle` | `ViewStyle` | `null` | For web TVs cursor handling. Style of the view which wraps the ascending arrow. Hover this view will trigger the scroll. |
| `descendingArrow` | `ReactElement` | `null` | For web TVs cursor handling. Optional component to display as the arrow to scroll on the descending order. |
| `descendingArrowContainerStyle` | `ViewStyle` | `null` | For web TVs cursor handling. Style of the view which wraps the descending arrow. Hover this view will trigger the scroll. |
| `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. |
| Name | Type | Default | Description |
| ------------------------------- | -------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `horizontal` | `boolean` | `false` | Determines if the scrolling orientation is horizontal. If `false`, the scrolling orientation will be vertical. |
| `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. |
| `style` | `ViewStyle` | `null` | Style for the ScrollView. This can be any valid React Native style object. |
| `children` | `ReactNode` | `null` | Child elements of the component. They are expected to be one or multiple `SpatialNavigationNode` elements. |
| `ascendingArrow` | `ReactElement` | `null` | For web TVs cursor handling. Optional component to display as the arrow to scroll on the ascending order. |
| `ascendingArrowContainerStyle` | `ViewStyle` | `null` | For web TVs cursor handling. Style of the view which wraps the ascending arrow. Hover this view will trigger the scroll. |
| `descendingArrow` | `ReactElement` | `null` | For web TVs cursor handling. Optional component to display as the arrow to scroll on the descending order. |
| `descendingArrowContainerStyle` | `ViewStyle` | `null` | For web TVs cursor handling. Style of the view which wraps the descending arrow. Hover this view will trigger the scroll. |
| `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. |
| `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. |

## Usage

Expand All @@ -153,7 +154,7 @@ const FocusableNode = () => (
</SpatialNavigationNode>
);

<SpatialNavigationScrollView horizontal={true} style={{ padding: 20 }} offsetFromStart={10}>
<SpatialNavigationScrollView horizontal style={{ padding: 20 }} offsetFromStart={10}>
<FocusableNode />
<FocusableNode />
<FocusableNode />
Expand Down
2 changes: 1 addition & 1 deletion packages/example/src/design-system/components/Box.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ interface Props {
paddingTop?: keyof Theme['spacings'];
padding?: keyof Theme['spacings'];
testID?: string;
style?: ViewStyle;
children: ReactNode;
}

Expand Down Expand Up @@ -64,6 +65,5 @@ const StyledView = styled(View, {
paddingLeft: paddingLeft && theme.spacings[paddingLeft],
paddingTop: paddingTop && theme.spacings[paddingTop],
padding: padding && theme.spacings[padding],
alignSelf: 'stretch',
}),
);
1 change: 1 addition & 0 deletions packages/example/src/pages/GridWithLongNodesPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const GridWithLongNodesPage = () => {
<CenteringView>
<GridContainer>
<SpatialNavigationScrollView
useCssScroll
offsetFromStart={HEADER_SIZE + 20}
ascendingArrow={<BottomArrow />}
ascendingArrowContainerStyle={styles.bottomArrowContainer}
Expand Down
2 changes: 1 addition & 1 deletion packages/lib/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { configureRemoteControl } from './spatial-navigation/configureRemoteCont
export { Directions } from '@bam.tech/lrud';
export { SpatialNavigationNode } from './spatial-navigation/components/Node';
export { SpatialNavigationRoot } from './spatial-navigation/components/Root';
export { SpatialNavigationScrollView } from './spatial-navigation/components/ScrollView';
export { SpatialNavigationScrollView } from './spatial-navigation/components/ScrollView/ScrollView';
export { SpatialNavigationView } from './spatial-navigation/components/View';
export { DefaultFocus } from './spatial-navigation/context/DefaultFocusContext';
export { SpatialNavigationVirtualizedList } from './spatial-navigation/components/virtualizedList/SpatialNavigationVirtualizedList';
Expand Down
263 changes: 0 additions & 263 deletions packages/lib/src/spatial-navigation/components/ScrollView.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react';
import { ViewStyle, ScrollView } from 'react-native';
import { CustomScrollView } from './CustomScrollView/CustomScrollView';
import { CustomScrollViewRef } from './types';

type Props = {
useNativeScroll: boolean;

horizontal?: boolean;
children: React.ReactNode;
style?: ViewStyle;
contentContainerStyle?: ViewStyle;
scrollDuration?: number;
onScroll?: (event: { nativeEvent: { contentOffset: { y: number; x: number } } }) => void;
testID?: string;
};

export const AnyScrollView = React.forwardRef<CustomScrollViewRef, Props>(
({ useNativeScroll, ...props }: Props, ref) => {
if (useNativeScroll) {
return (
<ScrollView
ref={ref as React.RefObject<ScrollView>}
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
scrollEnabled={false}
scrollEventThrottle={16}
{...props}
/>
);
}

return <CustomScrollView ref={ref} {...props} />;
},
);

AnyScrollView.displayName = 'AnyScrollView';
Loading

0 comments on commit cc9e4cd

Please sign in to comment.