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

@lp-labs/react-split-pane

v0.1.0

Published

Accessible React split panes with pointer/keyboard resizing and layout persistence.

Readme

@lp-labs/react-split-pane

Resizable React panels with pointer/touch and keyboard controls, size constraints and optional persistence. React 18+ peer only; no runtime dependencies or CSS imports. Includes TypeScript, ESM, CommonJS and browser entries.

Installation

npm install @lp-labs/react-split-pane

Requires React 18 or later in the host application. Pointer resizing requires a browser with Pointer Events. Persistence requires browser storage or a custom synchronous storage adapter. Server-side rendering is supported; Node.js consumers require Node.js 18 or later.

Quick Start

import SplitPane, { Pane } from '@lp-labs/react-split-pane';

export default function Example() {
  return (
    <SplitPane storageKey="editor-layout" style={{ height: 500 }}>
      <Pane id="files" label="Files" defaultSize={25} minSize={15} maxSize={50}>
        Files
      </Pane>
      <Pane id="editor" label="Editor" minSize={20}>
        Editor
      </Pane>
    </SplitPane>
  );
}

Pane API

Use at least two direct Pane children; nest another SplitPane inside a Pane for complex layouts. All sizes and bounds are percentages of available pane space, excluding gutters. Pane props: id, label, defaultSize, minSize (0), maxSize (100), styles and div attributes. Size constraints must admit a total of 100%; impossible constraints throw. Missing defaults share the remaining size and layouts are normalized to the bounds.

SplitPane API

| Prop | Default | Description | | --- | --- | --- | | direction | 'horizontal' | Side-by-side panes; 'vertical' stacks them | | layout / defaultLayout | pane defaults | Controlled or initial percentage sizes | | onLayoutChange(layout, { source }) | none | Requested or restored layout | | onResizeStart(layout) | none | Start of a pointer or keyboard resize | | onResizeEnd(layout, { cancelled }) | none | Completed or canceled resize | | disabled | false | Disable interactive resizing | | step | 1 | Keyboard increment in percentage points | | largeStep | 10 | Shift-key increment in percentage points | | gutterSize | 8 | Separator width or height in pixels | | storageKey | none | Opt into persistence under this key | | storage | window.localStorage | Synchronous getItem/setItem adapter | | onPersistenceError(error) | none | Invalid stored data or storage failures |

Standard div attributes and styles are supported. Controlled layout requires applying onLayoutChange; defaultLayout initializes internal state only. The wrapper defaults to 100% width and 300px height. Set a definite height for stacked layouts. Pane overflow scrolls independently.

Keyboard And Pointer Controls

Separators expose ARIA orientation, current value and min/max. Left/Right resize side-by-side panes; Up/Down resize stacked panes. Shift uses largeStep; Home/End reach the allowed limits. Pointer moves only affect adjacent panes. Escape, pointer cancellation or window blur restores the drag-start layout. No collapse/expand, pixel bounds, automatic snapping or RTL inversion is included.

Layout Persistence

storageKey opts into localStorage, read after mount for SSR-safe markup. Provide stable pane IDs when persisting. Stored records are accepted only when their IDs, order and direction match; bounds are revalidated. Successful pointer drops, keyboard changes and imperative updates persist; canceled drags do not. storage can provide custom synchronous getItem/setItem; onPersistenceError receives corrupt JSON, storage denial or quota errors. Controlled layouts are not restored automatically. No initial automatic write overwrites an existing record.

Imperative API And Limits

The ref exposes getLayout(), setLayout(percentages) and resetLayout(). The pure helpers normalizeLayout and resizeLayout are exported. Constraint changes normalize rendered sizes; changed pane structure cancels any current drag. The component uses flexbox and does not bundle ResizeObserver or an animation framework. Focus appearance uses native browser outlines.

Support

Support maintenance with a PayPal donation.

Author

Created by Libin Prasanth.