Kenan Yusuf

Cover Image for Resizable split pane layouts for React applications with react-resplit

Resizable split pane layouts for React applications with react-resplit

Not long ago, I published react-resplit, an open source library for creating resizable split pane layouts in React applications.

Some of the key features that sets it apart from others in the space:

  • Flexible hook-based API that works with any styling method
  • Built with modern CSS, a grid-based layout and custom properties
  • Works with any amount of panes in a vertical or horizontal layout
  • Built following the Window Splitter pattern for accessibility and keyboard controls

Usage

It is pretty simple to use too, start by installing the package:

npm install react-resplit

Then import the useResplit hook and register the container, panes and splitters.

import { useResplit } from "react-resplit";

function App() {
  const { getContainerProps, getSplitterProps, getPaneProps } = useResplit({
    direction: "horizontal",
  });

  return (
    <div {...getContainerProps()}>
      <div {...getPaneProps(0, { initialSize: "0.5fr" })}>Pane 1</div>
      <div {...getSplitterProps(1, { size: "10px" })} />
      <div {...getPaneProps(2, { initialSize: "0.5fr" })}>Pane 2</div>
    </div>
  );
}

Styling

The container, splitter and pane elements are all unstyled by default apart from a few styles that are necessary for the layout - this is intentional so that the library remains flexible.

Resplit will apply the correct cursor based on the direction provided to the hook.

As a basic example, you could provide a className prop to the splitter elements and style them as a solid 10px divider.

<div className="splitter" {...getSplitterProps(1, { size: "10px" })} />
.splitter {
  width: 100%;
  height: 100%;
  background: #ccc;
}

Accessibility

Resplit has been implemented using guidence from the Window Splitter pattern.

In addition to built-in accessibility considerations, you should also ensure that splitters are correctly labelled.

If the primary pane has a visible label, the aria-labelledby attribute can be used.

<div {...getPaneProps(0)}>
  <h2 id="pane-1-label">Pane 1</h2>
</div>
<div aria-labelledby="pane-1-label" {...getSplitterProps(1)} />

Alternatively, if the pane does not have a visible label, the aria-label attribute can be used.

<div aria-label="Pane 1" {...getSplitterProps(1)} />

Interested in learning more?

For a more detailed look at the library, check out the GitHub repository.