Skip to content

Commit 52ba9a3

Browse files
authored
feat: add support for MasonryFlashlist (#39)
Key Highlights: - add support for MasonryFlashlist - updated docs for new component - added usage in example application
1 parent 0703df4 commit 52ba9a3

File tree

15 files changed

+472
-1
lines changed

15 files changed

+472
-1
lines changed

docs/docs/01-getting-started.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Before you can use `react-native-header`, you need to have the following librari
3232

3333
If you haven't installed these libraries yet, please follow the installation instructions on their respective documentation pages.
3434

35-
If you intend to use the [FlashListWithHeaders](/docs/components/flash-list-with-headers) component, please ensure that you review the [Compatibilty table](/docs/getting-started#compatibility) above and install the correct versions of each library.
35+
If you intend to use the [FlashListWithHeaders](/docs/components/flash-list-with-headers) or [MasonryFlashListWithHeaders](/docs/components/masonry-flash-list-with-headers) component, please ensure that you review the [Compatibilty table](/docs/getting-started#compatibility) above and install the correct versions of each library.
3636

3737
## Installation
3838

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
---
2+
title: MasonryFlashListWithHeaders
3+
hide_table_of_contents: false
4+
slug: /components/masonry-flash-list-with-headers
5+
description: Shopify's MasonryFlashList paired with React Native Header.
6+
---
7+
8+
Component that extends Shopify's [MasonryFlashListFlashList](https://shopify.github.io/flash-list/docs/guides/masonry) to add support for
9+
headers exported from this library.
10+
11+
The implementation of this component relies on the [HeaderComponent](/docs/components/flash-list-with-headers#headercomponent)
12+
and [LargeHeaderComponent](/docs/components/flash-list-with-headers#largeheadercomponent) props.
13+
The [HeaderComponent](/docs/components/flash-list-with-headers#headercomponent) is rendered above
14+
the MasonryFlashList and the [LargeHeaderComponent](/docs/components/flash-list-with-headers#largeheadercomponent)
15+
is rendered as the `ListHeaderComponent` of the MasonryFlashList. Using these two props will allow for
16+
animations/built-in features in this library to work properly.
17+
18+
## Note
19+
20+
This component is only available in react-native-header version >= `0.14.x`. Please review the [Compatibility matrix](/docs/getting-started#compatibility) and ensure
21+
you have the correct dependencies installed in your project before using this component.
22+
23+
## Props
24+
25+
This component uses the MasonryFlashList under the hood, which inherits [all of the props
26+
from the MasonryFlashList component](https://shopify.github.io/flash-list/docs/guides/masonry).
27+
28+
### HeaderComponent
29+
30+
The component to render above the MasonryFlashList. This accepts a function that returns a React Element
31+
to display as the header. The function will be called with the following arguments:
32+
33+
- `showNavBar`: An animated value that will be 0 when the header's subcomponents should be hidden
34+
and 1 when they should be shown. This is useful for animating the header's subcomponents. The
35+
[Header](/docs/components/header) component uses this value to animate its left, center, and
36+
right children.
37+
38+
### LargeHeaderComponent
39+
40+
An optional component to render as the large header for this component. This accepts a function
41+
that returns a React Element to display as the large header. The function will be called with the
42+
following arguments:
43+
44+
- `scrollY`: An animated value that keeps track of the current scroll position of the MasonryFlashList.
45+
This prop is useful for creating custom animations on the large header. In our [example](/docs/example),
46+
we use the [ScalingView](/docs/components/scaling-view) component to scale the large header
47+
when the user pulls down on the MasonryFlashList (to mimic native iOS behaviour).
48+
- `showNavBar`: An animated value that keeps track of whether or not the small header is hidden.
49+
This prop is useful if you want to create your own custom animations based on whether or not the
50+
small header is hidden.
51+
52+
### LargeHeaderSubtitleComponent
53+
54+
An optional component to render as a subtitle for the large header for this component. This accepts a function
55+
that returns a React Element to display as the large header subtitle. The function will be called with the
56+
following arguments:
57+
58+
- `scrollY`: An animated value that keeps track of the current scroll position of the MasonryFlashList.
59+
This prop is useful for creating custom animations on the large header. In our [example](/docs/example),
60+
we use the [ScalingView](/docs/components/scaling-view) component to scale the large header
61+
when the user pulls down on the FlatList (to mimic native iOS behaviour).
62+
- `showNavBar`: An animated value that keeps track of whether or not the small header is hidden.
63+
This prop is useful if you want to create your own custom animations based on whether or not the
64+
small header is hidden.
65+
66+
### ignoreLeftSafeArea
67+
68+
An optional boolean that determines whether or not to ignore the left safe area. Defaults to
69+
`false`. The safe area adjustments are used to make sure that the scroll container does not
70+
overlap with the notch/headers on different phones - leave this prop as false if you want to
71+
respect those safe areas.
72+
73+
### ignoreRightSafeArea
74+
75+
An optional boolean that determines whether or not to ignore the right safe area. Defaults to
76+
`false`. The safe area adjustments are used to make sure that the scroll container does not
77+
overlap with the notch/headers on different phones - leave this prop as `false` if you want to
78+
respect those safe areas.
79+
80+
### disableAutoFixScroll
81+
82+
An optional to disable the auto fix scroll mechanism. This is useful if you want to disable the
83+
auto scroll when the large header is partially visible. Defaults to `false`.
84+
85+
### containerStyle
86+
87+
An optional style object that will be applied to the parent container of the scroll container.
88+
89+
### largeHeaderContainerStyle
90+
91+
An optional style object that will be applied to the large header container.
92+
93+
### largeHeaderShown
94+
95+
An optional animated [Shared Value](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/shared-values/)
96+
that will be mutated by the library when the large header is shown or hidden. This is useful if you
97+
would like to track when the large header is shown or hidden.
98+
99+
### onLargeHeaderLayout
100+
101+
An optional callback that will be called when the large header is laid out. This is useful if you
102+
want to access the layout of the large header to calculate the height of the large header.
103+
104+
### absoluteHeader
105+
106+
This property controls whether or not the header component is absolutely positioned. This is useful
107+
if you want to render a header component that allows for transparency.
108+
109+
**Note**: This is only available in version >= 0.9.0.
110+
111+
### initialAbsoluteHeaderHeight
112+
113+
This property is used when `absoluteHeader` is true. This is the initial height of the
114+
absolute header. Since the header's height is computed on its layout event, this is used
115+
to set the initial height of the header so that it doesn't jump when it is initially rendered.
116+
117+
**Note**: This is only available in version >= 0.9.0.
118+
119+
### headerFadeInThreshold
120+
121+
A number between 0 and 1 representing at what point the header should fade in,
122+
based on the percentage of the LargeHeader's height. For example, if this is set to 0.5,
123+
the header will fade in when the scroll position is at 50% of the LargeHeader's height.
124+
125+
Defaults to `1`.
126+
127+
**Note**: This is only available in version >= 0.10.0.
128+
129+
### disableLargeHeaderFadeAnim
130+
131+
Whether or not the LargeHeaderComponent should fade in and out. Defaults to `false`.
132+
133+
**Note**: This is only available in version >= 0.10.0.
134+
135+
### onScrollWorklet
136+
137+
A custom worklet that allows custom tracking scroll container's
138+
state (i.e., its scroll contentInset, contentOffset, etc.). Please
139+
ensure that this function is a [worklet](https://docs.swmansion.com/react-native-reanimated/docs/2.x/fundamentals/worklets/).
140+
141+
Since the library uses the `onScroll` prop to handle animations internally and [reanimated
142+
does not currently allow for multiple onScroll handlers](https://github.com/software-mansion/react-native-reanimated/discussions/1763),
143+
you must use this property to track the state of the scroll container's state.
144+
145+
An example is shown below:
146+
147+
```tsx
148+
const scrollHandlerWorklet = (evt: NativeScrollEvent) => {
149+
'worklet';
150+
console.log('offset: ', evt.contentOffset);
151+
};
152+
```
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

example/src/navigation/AppNavigation.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { createNativeStackNavigator } from '@react-navigation/native-stack';
33
import type { RootStackParamList } from './types';
44
import {
55
FlashListUsageScreen,
6+
MasonryFlashListUsageScreen,
67
FlatListUsageScreen,
78
HomeScreen,
89
ProfileScreen,
@@ -29,6 +30,7 @@ export default () => (
2930
<Stack.Screen name="SimpleUsageScreen" component={SimpleUsageScreen} />
3031
<Stack.Screen name="FlatListUsageScreen" component={FlatListUsageScreen} />
3132
<Stack.Screen name="FlashListUsageScreen" component={FlashListUsageScreen} />
33+
<Stack.Screen name="MasonryFlashListUsageScreen" component={MasonryFlashListUsageScreen} />
3234
<Stack.Screen name="SectionListUsageScreen" component={SectionListUsageScreen} />
3335
<Stack.Screen name="InvertedUsageScreen" component={InvertedUsageScreen} />
3436
<Stack.Screen

example/src/navigation/types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export type RootStackParamList = {
77
SimpleUsageScreen: undefined;
88
FlatListUsageScreen: undefined;
99
FlashListUsageScreen: undefined;
10+
MasonryFlashListUsageScreen: undefined;
1011
SectionListUsageScreen: undefined;
1112
TwitterProfileScreen: undefined;
1213
HeaderSurfaceComponentUsageScreen: undefined;
@@ -43,6 +44,11 @@ export type FlashListUsageScreenNavigationProps = NativeStackScreenProps<
4344
'FlashListUsageScreen'
4445
>;
4546

47+
export type MasonryFlashListUsageScreenNavigationProps = NativeStackScreenProps<
48+
RootStackParamList,
49+
'MasonryFlashListUsageScreen'
50+
>;
51+
4652
export type SectionListUsageScreenNavigationProps = NativeStackScreenProps<
4753
RootStackParamList,
4854
'SectionListUsageScreen'

example/src/screens/Home.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ const SCREEN_LIST_CONFIG: ScreenConfigItem[] = [
3333
route: 'FlashListUsageScreen',
3434
description: "A simple example with Shopify's FlashList.",
3535
},
36+
{
37+
name: 'MasonryFlashList Example',
38+
route: 'MasonryFlashListUsageScreen',
39+
description: "A simple example with Shopify's MasonryFlashList.",
40+
},
3641
{
3742
name: 'SectionList Example',
3843
route: 'SectionListUsageScreen',

example/src/screens/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export { default as ProfileScreen } from './Profile';
55
export { default as SimpleUsageScreen } from './usage/Simple';
66
export { default as FlatListUsageScreen } from './usage/FlatList';
77
export { default as FlashListUsageScreen } from './usage/FlashList';
8+
export { default as MasonryFlashListUsageScreen } from './usage/MasonryFlashList';
89
export { default as SectionListUsageScreen } from './usage/SectionList';
910
export { default as InvertedUsageScreen } from './usage/Inverted';
1011
export { default as SurfaceComponentUsageScreen } from './usage/SurfaceComponent';

0 commit comments

Comments
 (0)