npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@rific/scroll-view

v0.2.0

Published

Blur styled scroll system for React Native. Floating headers/footers, keyboard awareness, and scroll-away chrome

Readme

@rific/scroll-view

Blur-chrome scroll system for React Native. Drop-in replacements for ScrollView, FlatList, and SectionList with floating headers and footers, pull-to-search, keyboard awareness, horizontal paging, and frosted-glass chrome.

Installation

npm install @rific/scroll-view

Peer dependencies

npm install @rific/auto-paper react-native-reanimated react-native-gesture-handler react-native-safe-area-context react-native-paper react-native-keyboard-controller

Quick start

Wrap your screen in ScrollViewProvider, add a ScrollViewHeader, then drop in one of the scroll components.

import { ScrollViewProvider, ScrollViewHeader, FlatList } from '@rific/scroll-view'

export default function MyScreen() {
  return (
    <ScrollViewProvider>
      <ScrollViewHeader title="My Screen" backAction={() => router.back()} />
      <FlatList data={items} renderItem={({ item }) => <Row item={item} />} keyExtractor={(item) => item.id} />
    </ScrollViewProvider>
  )
}

For app-wide defaults, wrap your root layout with ScrollViewSettingsProvider.

import { ScrollViewSettingsProvider } from '@rific/scroll-view'

export default function RootLayout({ children }) {
  return (
    <ScrollViewSettingsProvider initialValue={{ snapBack: true }}>
      {children}
    </ScrollViewSettingsProvider>
  )
}

Components

ScrollViewSettingsProvider

App-wide defaults for scroll settings. Wrap your root layout to set global defaults.

| Prop | Type | Description | |------|------|-------------| | children | ReactNode | — | | initialValue | Partial<ScrollViewSettings> | Initial settings applied once on mount | | onChange | (settings: ScrollViewSettings) => void | Called whenever settings change |


ScrollViewProvider

Screen-level provider that owns header/footer state and scroll position. Must wrap ScrollViewHeader, ScrollViewFooter, and the scroll component.

| Prop | Type | Default | Description | |------|------|---------|-------------| | blur | boolean | system | Enable frosted-glass backdrop on header/footer | | fixed | boolean | false | Pin both header and footer (overrides headerFixed/footerFixed) | | headerFixed | boolean | false | Pin header; overrides settings default | | footerFixed | boolean | false | Pin footer; overrides settings default | | snapBack | boolean | false | Snap header and footer back when scrolling up | | snapBackHeader | boolean | — | Override snapBack for header only | | snapBackFooter | boolean | — | Override snapBack for footer only | | tabBarHeight | number | 60 | Used to compute safe scroll height |


ScrollViewHeader

Floating header with blur backdrop, title, back action, trailing action, and built-in progress bar. Place it as a direct child of ScrollViewProvider.

| Prop | Type | Default | Description | |------|------|---------|-------------| | title | string | — | Center title text | | caption | string | — | Subtitle below title | | centerContent | ReactNode | — | Replaces title/caption with custom content | | children | ReactNode | — | Left-side content (icon buttons, etc.) | | backAction | () => void | — | Renders a back button and calls this on press | | backActionFixed | boolean | settings | Keep back button visible as header scrolls away | | trailingAction | ReactNode | — | Right-side floating action | | trailingActionFixed | boolean | true | Keep trailing action visible as header scrolls away | | actionSize | number | 48 | Size of floating action buttons | | iconSize | number | actionSize/2 | Icon size inside action buttons | | actionStyle | ViewStyle | — | Style applied to action button backgrounds | | style | ViewStyle | — | Style applied to the header content area | | topInset | boolean | true | Pad for safe area top inset |


ScrollViewFooter

Floating footer with blur backdrop. Place it as a direct child of ScrollViewProvider.

| Prop | Type | Description | |------|------|-------------| | children | ReactNode | Footer content | | style | ViewStyle | Style applied to the inner row |


ScrollView

Drop-in for React Native's ScrollView. Accepts all ScrollViewProps plus:

| Prop | Type | Description | |------|------|-------------| | chipProps | ChipProps | Customize the scroll-to-top chip (label, style, etc.) | | chipThreshold | number | Scroll offset (px) before the chip appears. Default 100 | | footerFixed | boolean | Pin footer for this scroll view; overrides provider | | gesture | GestureType | Compose with an external RNGH gesture | | headerFixed | boolean | Pin header for this scroll view; overrides provider | | keyboardAware | boolean | Add keyboard height to bottom content inset | | onChipPress | () => void | Additional callback fired when the chip is pressed | | onRefresh | () => void | Enables pull-to-refresh | | pullSearchHeight | number | Reserve space above content for PullSearch | | ref | RefObject<RNScrollView> | Forward ref to the underlying scroll view | | refreshing | boolean | Controlled refreshing state |


FlatList

Drop-in for React Native's FlatList. Accepts all FlatListProps<T> plus:

| Prop | Type | Description | |------|------|-------------| | chipProps | ChipProps | Customize the scroll-to-top/start chip (label, style, etc.) | | chipThreshold | number | Scroll offset (px) before the chip appears. Default 100 | | footerFixed | boolean | Pin footer for this list; overrides provider | | gesture | GestureType | Compose with an external RNGH gesture | | headerFixed | boolean | Pin header for this list; overrides provider | | keyboardAware | boolean | Add keyboard height to bottom content inset | | onChipPress | () => void | Additional callback fired when the chip is pressed | | onRefresh | () => Promise<void> \| void | Enables pull-to-refresh | | pullSearchHeight | number | Reserve space above content for PullSearch | | ref | RefObject<RNFlatList> | Forward ref to the underlying list | | renderFilters | ReactNode | Rendered below ListHeaderComponent, above list items |

Performance props are user-overridable with sensible defaults:

| Prop | Default | |------|---------| | initialNumToRender | 20 | | maxToRenderPerBatch | 50 | | windowSize | 100 | | removeClippedSubviews | false | | showsHorizontalScrollIndicator | horizontal | | showsVerticalScrollIndicator | !horizontal |

When horizontal and pagingEnabled are both true and data has more than one item, horizontal dot indicators render automatically.


SectionList

Drop-in for React Native's SectionList. Accepts all SectionListProps<ItemT, SectionT> (except horizontal) plus the same set of library props as FlatList. Custom sticky section headers are supported — pass renderSectionHeader and stickySectionHeadersEnabled and the library renders them via an animated overlay so they properly account for the floating header offset.


CustomList

Wraps any list component that follows the FlatList scroll API (e.g. FlashList). Pass the component via the component prop; all other props are forwarded.

import { FlashList } from '@shopify/flash-list'
import { CustomList } from '@rific/scroll-view'

<CustomList component={FlashList} data={items} renderItem={renderItem} estimatedItemSize={80} />

| Prop | Type | Description | |------|------|-------------| | chipProps | ChipProps | Customize the scroll-to-top chip (label, style, etc.) | | component | ComponentType<P> | The list component to render | | footerFixed | boolean | Pin footer; overrides provider | | gesture | GestureType | Compose with an external RNGH gesture | | headerFixed | boolean | Pin header; overrides provider | | keyboardAware | boolean | Add keyboard height to bottom content inset | | onRefresh | () => Promise<void> \| void | Enables pull-to-refresh | | pullSearchHeight | number | Reserve space above content for PullSearch | | renderFilters | ReactNode | Rendered below ListHeaderComponent, above list items | | scrollRef | RefObject<{ scrollToOffset }> | Forward ref to the underlying list |

The underlying component receives contentInset, contentOffset, onScroll, refreshControl, and scrollEventThrottle — props it must support for the library to function.


ChipProps

Passed via chipProps on any scroll component to customise the floating scroll-to-top chip. Accepts all Chip props from @rific/auto-paper except compact, icon, and onPress (which are managed by the library), plus:

| Prop | Type | Description | |------|------|-------------| | label | ReactNode | Override the default label ("Top" / "Start") | | style | ViewStyle | Merged with the chip's default style |

<FlatList
  chipProps={{ label: 'Back to top', style: { opacity: 0.9 } }}
  data={items}
  renderItem={renderItem}
  keyExtractor={(item) => item.id}
/>

PullSearch

A search bar that lives above the list content and is revealed by pulling down. Use alongside pullSearchHeight on the scroll component.

import { useRef, useState } from 'react'
import { FlatList, PullSearch, type PullSearchHandle } from '@rific/scroll-view'

export default function SearchScreen() {
  const searchRef = useRef<PullSearchHandle>(null)
  const [query, setQuery] = useState('')
  const [searchHeight, setSearchHeight] = useState(0)

  return (
    <ScrollViewProvider>
      <ScrollViewHeader title="Search" />
      <FlatList
        data={filteredItems}
        renderItem={renderItem}
        keyExtractor={(item) => item.id}
        pullSearchHeight={searchHeight}
        ListHeaderComponent={
          <PullSearch
            ref={searchRef}
            value={query}
            onChangeText={setQuery}
            onHeightChange={setSearchHeight}
            placeholder="Search…"
            debounce
          />
        }
      />
    </ScrollViewProvider>
  )
}

| Prop | Type | Description | |------|------|-------------| | onChangeText | (text: string) => void | Called with trimmed search text | | onHeightChange | (height: number) => void | Required — pass the height back as pullSearchHeight | | value | string | Controlled value | | placeholder | string | Placeholder text | | debounce | boolean | Debounce onChangeText by 500ms |

Ref methods: focus(), blur()


Hooks

useScrollView

Access scroll state and progress control from anywhere inside a ScrollViewProvider.

const { scrollPosition, scrollHeight, progressing, progress, setProgress, setProgressing } = useScrollView()

| Return | Type | Description | |--------|------|-------------| | scrollPosition | SharedValue<number> | Live scroll offset (Reanimated worklet-safe) | | scrollHeight | number | Visible scroll area height (window minus header/footer) | | progressing | boolean | Whether the header progress bar is visible | | progress | number \| null | Progress bar value (0–1), or null for indeterminate | | setProgress | (p: number \| null) => void | Set progress; pass null for indeterminate | | setProgressing | (b: boolean) => void | Show/hide the progress bar |

// Show an indeterminate progress bar while loading
useEffect(() => {
  setProgressing(true)
  fetchData().finally(() => setProgressing(false))
}, [])

useScrollViewSettings

Read and update scroll settings at runtime from anywhere inside ScrollViewSettingsProvider.

const { settings, set } = useScrollViewSettings()

// Toggle snap-back on the fly
set({ snapBack: true })

useKeyboardInset

Returns the current keyboard height, updating as the keyboard animates in and out. Useful when you need the keyboard height outside of a scroll component.

const keyboardHeight = useKeyboardInset()

Redux integration

If your app uses Redux, you can drive scroll settings from the store instead of (or in addition to) ScrollViewSettingsProvider.

// store.ts
import { scrollViewReducer } from '@rific/scroll-view'

export const store = configureStore({
  reducer: {
    scrollView: scrollViewReducer,
    // ...
  }
})
// Dispatch initial settings (e.g. from a remote config)
store.dispatch(scrollViewActions.initialize({ snapBack: true, headerFixed: false, footerFixed: false, backActionFixed: true }))

Settings reference

ScrollViewSettings defaults:

| Setting | Default | Description | |---------|---------|-------------| | headerFixed | false | Pin header globally | | footerFixed | false | Pin footer globally | | snapBack | false | Snap header and footer back when scrolling up | | snapBackHeader | — | Override snapBack for header only | | snapBackFooter | — | Override snapBack for footer only | | backActionFixed | true | Keep back button visible as header scrolls away |

Settings cascade: ScrollViewSettingsProviderScrollViewProvider → individual scroll component props. More specific values always win.