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

@fictjs/fict-remove-scroll

v0.3.4

Published

Scroll isolation primitives for Fict, based on react-remove-scroll.

Readme

@fictjs/fict-remove-scroll

Scroll isolation for Fict, based on react-remove-scroll.

It keeps scroll inside a lock boundary, can remove the body scrollbar without layout jump, supports nested scrollable areas, and keeps the sidecar split between a light UI wrapper and DOM side effects.

Installation

pnpm add @fictjs/fict-remove-scroll fict

Basic usage

/** @jsxImportSource fict */

import { render } from 'fict'
import { createSignal } from 'fict/advanced'
import { RemoveScroll } from '@fictjs/fict-remove-scroll'

function App() {
  const open = createSignal(false)

  return (
    <>
      <button onClick={() => open(!open())}>Toggle lock</button>
      {() =>
        open() ? (
          <RemoveScroll>
            <div style={{ maxHeight: '200px', overflow: 'auto' }}>Only this region scrolls</div>
          </RemoveScroll>
        ) : null
      }
    </>
  )
}

render(() => <App />, document.getElementById('app')!)

API

RemoveScroll accepts the same core surface as the React package:

  • children
  • enabled
  • allowPinchZoom
  • noRelative
  • noIsolation
  • inert
  • forwardProps
  • className
  • removeScrollBar
  • shards
  • as
  • gapMode
  • ref

Important behavior

  • enabled defaults to true.
  • removeScrollBar defaults to true.
  • inert defaults to false.
  • when multiple locks are mounted, only the last active one traps outer wheel/touch scroll
  • shards lets you whitelist extra DOM islands, including portaled content

forwardProps

By default the component wraps children in a host element:

<RemoveScroll className="scroll-shell">
  <div>content</div>
</RemoveScroll>

Set forwardProps to inject the lock props into a single child element instead:

<RemoveScroll forwardProps>
  <div className="scroll-shell">content</div>
</RemoveScroll>

As in the upstream package, the forwarded child must be a single Fict element node.

Fixed element helpers

RemoveScroll.classNames mirrors react-remove-scroll and re-exports the helper selectors from @fictjs/fict-remove-scroll-bar:

/** @jsxImportSource fict */

import { RemoveScroll } from '@fictjs/fict-remove-scroll'

function Sheet() {
  return (
    <RemoveScroll>
      <header className={RemoveScroll.classNames.zeroRight}>Fixed action bar</header>
      <main className={RemoveScroll.classNames.fullWidth}>Full-width content</main>
    </RemoveScroll>
  )
}

UI / sidecar split

Like the React package, the Fict version ships a light UI entry and a sidecar entry for manual code-splitting:

/** @jsxImportSource fict */

import { sidecar } from '@fictjs/use-sidecar'
import { RemoveScroll } from '@fictjs/fict-remove-scroll/UI'

const removeScrollSidecar = sidecar(() => import('@fictjs/fict-remove-scroll/sidecar'))

function DialogBody() {
  return (
    <RemoveScroll sideCar={removeScrollSidecar}>
      <div>Scrollable dialog content</div>
    </RemoveScroll>
  )
}

Fict-specific notes

  • Fict components mount once, so the implementation uses stable closures plus mutable refs instead of React state for capture callbacks.
  • To drive enabled, inert, removeScrollBar, or shards reactively across component boundaries, pass normal reactive JSX expressions or explicit prop(() => ...) getters where needed.
  • DOM event capture is emitted using Fict's runtime-friendly oncapture:* form internally, so the package works without relying on React-specific event semantics.

Testing coverage

The package test suite covers:

  • wrapper rendering and forwardProps
  • enabled toggling
  • body scrollbar locking and helper class names
  • inert mode pointer blocking
  • nested locks
  • shard whitelisting
  • UI + async sidecar loading

License

MIT