react-native-sticky-parallax-header

repository·master·Indexed 24 days ago

https://github.com/netguru/sticky-parallax-header

A React Native library for creating custom sticky parallax header layouts on iOS, Android, and web. It supports Tabbed, Avatar, and Details headers, and provides integration with Shopify's FlashList via the withStickyHeaderFlashList HOC and useStickyHeaderFlashListScrollProps hook. The library requires React Native 0.64+, react-native-reanimated, and react-native-safe-area-context.

Tokens
22.2K
Snippets
29
Records
83
Agent score
84%

What's inside react-native-sticky-parallax-header

  1. Overview of react-native-sticky-parallax-header components

    master

    The react-native-sticky-parallax-header library provides several ways to implement sticky parallax headers in React Native (iOS, Android, and Web). The components are categorized into three main types:

    1. Primitive components: Low-level components that provide the core sticky header setup for standard scrollable lists.
    2. Predefined components: Ready-to-use header layouts for common UI patterns like Tabbed, Avatar, or Details headers.
    3. FlashList HOCs: Higher-order components specifically designed to add sticky header capabilities to Shopify's FlashList.

    Depending on your needs, you can use these out-of-the-box or use the provided HOCs and hooks to build entirely custom sticky header layouts.

  2. How `useStickyHeaderScrollProps` and `StickyHeader` work together

    master

    The useStickyHeaderScrollProps hook is the engine for the parallax and snapping behavior. It is a generic hook that needs to know the type of scroll component it is enhancing (e.g., ScrollView, FlatList<ItemT>, or SectionList<ItemT, SectionT>).

    It returns several key properties:

    • onScroll, onMomentumScrollEnd, onScrollEndDrag: Event handlers that must be passed to the scroll component to manage the snapping logic.
    • scrollValue: A value representing the current scroll position, which can be passed to custom header components (like a HeaderBar or Foreground) to drive parallax animations.
    • scrollHeight: The total height of the scrollable content, useful for sizing header containers.
    • scrollViewRef: A ref to be attached to the scroll component.

    These props are then consumed by the StickyHeader component (or its variants) and the renderHeader/renderTabs functions to synchronize the UI with the scroll position.

  3. Install prerequisites for react-native-sticky-parallax-header

    master

    The library requires react-native-reanimated and react-native-safe-area-context to function. Install them using yarn:

    yarn add react-native-reanimated react-native-safe-area-context

    After installing these dependencies, you must complete the following steps:

    1. Follow the official Reanimated installation guide to ensure it is correctly configured in your project.
    2. Install iOS pods by running npx pod-install.
    3. Wrap your application's root component with SafeAreaProvider from react-native-safe-area-context.
  4. Implement pull-to-refresh in StickyHeaderScrollView

    master

    All exported components inherit the props of their underlying scroll component. To use the default refresh control, simply pass the onRefresh and refreshing props directly to the component.

    If you require a custom setup (such as custom styles or colors), use the refreshControl prop to pass a custom component (e.g., RefreshControl).

      <StickyHeaderScrollView
        // ...
        onRefresh={onRefresh}
        refreshing={refreshing}
        // ...
      >
        {/** content */}
      </StickyHeaderScrollView>
  5. Deploy the documentation website to GitHub Pages

    master

    You can deploy the built website to the gh-pages branch of your GitHub repository using the yarn deploy command. You must provide your GitHub username via the GIT_USER environment variable. If you are using SSH for Git operations, set USE_SSH=true.

    GIT_USER=<Your GitHub username> USE_SSH=true yarn deploy
  6. Render icons in tabs

    master

    The icon property within a tab object in the tabs array can accept either a direct React component or a function.

    • Static Icon: Pass a React component directly to use the same icon for both active and inactive states.
    • Dynamic/Active Icon: Pass a function that receives an active boolean argument. This allows you to return different components based on whether the tab is currently selected.
    <TabbedHeaderPager
      tabs={[
        {
          title: 'Development',
          icon: (active) => (active ? <ActiveIcon /> : <Icon />),
        },
      ]}
      // ...
    >
      {/** content */}
    </TabbedHeaderPager>
  7. Use renderHeaderBar for a custom Header component

    master

    To implement a fully custom header (e.g., adding a back button, close button, or custom animations), use the renderHeaderBar prop. This prop accepts a function that returns a component.

    To create elements that react to the scroll position (like a title that fades in only when the header is collapsed), you can capture the vertical content offset via the onScroll prop and pass it to your custom header component using a Reanimated shared value.

    // 1. Capture scroll value
    const scrollValue = useSharedValue(0);
    const onScroll = (e) => {
      'worklet';
      scrollValue.value = e.contentOffset.y;
    };
    
    // 2. Create custom header using the shared value
    const HeaderBar = ({ scrollValue }) => {
      const animatedStyle = useAnimatedStyle(() => ({
        opacity: interpolate(scrollValue.value, [0, 60, 90], [0, 0, 1], Extrapolate.CLAMP)
      }));
    
      return (
        <View>
          <Animated.View style={animatedStyle}>
            <Text>Custom Title</Text>
          </Animated.View>
        </View>
      );
    };
    
    // 3. Pass to TabbedHeaderPager
    <TabbedHeaderPager
      onScroll={onScroll}
      renderHeaderBar={() => <HeaderBar scrollValue={scrollValue} />}
      {/* ... other props */}
    />
  8. Create a custom header layout

    master

    To implement a custom header layout, you must combine the useStickyHeaderScrollProps hook with either the StickyHeader component (which supports ScrollView, FlatList, or SectionList) or a custom scroll component wrapped in the withStickyHeader Higher-Order Component (HOC).

    Implementation Steps:

    1. Initialize Scroll Props: Call useStickyHeaderScrollProps and pass the configuration object. This hook provides the necessary props to create the "snap effect" behavior.
    2. Pass Props to Scroll Component: Pass the returned props (such as onScroll, onMomentumScrollEnd, and onScrollEndDrag) to your StickyHeader component or your withStickyHeader decorated component.
    3. Render Custom UI: Use the renderHeader and renderTabs props on the sticky header component to define your custom header or tabs layout.

    Configuration Options for useStickyHeaderScrollProps:

    • parallaxHeight: The height of the parallax area.
    • snapStartThreshold: The threshold at which snapping begins.
    • snapStopThreshold: The threshold at which snapping stops.
    • snapToEdge: Boolean to determine if snapping should go to the edge.
    const { 
      onMomentumScrollEnd, 
      onScroll, 
      onScrollEndDrag, 
      scrollHeight, 
      scrollValue, 
      scrollViewRef 
    } = useStickyHeaderScrollProps<ScrollView>({
      parallaxHeight: PARALLAX_HEIGHT,
      snapStartThreshold: SNAP_START_THRESHOLD,
      snapStopThreshold: SNAP_STOP_THRESHOLD,
      snapToEdge: true,
    });
    
    // ...
    
    <StickyHeaderScrollView
      ref={scrollViewRef}
      onScroll={onScroll}
      onMomentumScrollEnd={onMomentumScrollEnd}
      onScrollEndDrag={onScrollEndDrag}
      renderHeader={() => (
        <View pointerEvents="box-none" style={{ height: scrollHeight }}>
          <Foreground scrollValue={scrollValue} />
        </View>
      )}
      renderTabs={() => (
        <View style={styles.tabContainer}>
          <Tabs />
        </View>
      )}
    >
      {/* Scroll Content */}
    </StickyHeaderScrollView>