UNPKG

@gfazioli/mantine-split-pane

Version:

A Mantine 9 React component for resizable split pane layouts with 7 resizer variants, context-based prop inheritance, responsive orientation, and dynamic pane generation.

224 lines (172 loc) 6.98 kB
# Mantine Split Pane Component <img alt="Mantine Split Pane" src="https://github.com/gfazioli/mantine-split-pane/blob/master/logo.jpeg" /> <div align="center"> [![NPM version](https://img.shields.io/npm/v/%40gfazioli%2Fmantine-split-pane?style=for-the-badge)](https://www.npmjs.com/package/@gfazioli/mantine-split-pane) [![NPM Downloads](https://img.shields.io/npm/dm/%40gfazioli%2Fmantine-split-pane?style=for-the-badge)](https://www.npmjs.com/package/@gfazioli/mantine-split-pane) [![NPM Downloads](https://img.shields.io/npm/dy/%40gfazioli%2Fmantine-split-pane?style=for-the-badge&label=%20&color=f90)](https://www.npmjs.com/package/@gfazioli/mantine-split-pane) ![NPM License](https://img.shields.io/npm/l/%40gfazioli%2Fmantine-split-pane?style=for-the-badge) --- [<kbd> <br/> ❤️ If this component has been useful to you or your team, please consider becoming a sponsor <br/> </kbd>](https://github.com/sponsors/gfazioli?o=esc) </div> ## Overview A Mantine 9 React component for resizable split pane layouts with 7 resizer variants, context-based prop inheritance, responsive orientation, and dynamic pane generation. This component is created on top of the [Mantine](https://mantine.dev/) library. It requires **Mantine 9.x** and **React 19**. > [!note] > > → [Demo and Documentation](https://gfazioli.github.io/mantine-split-pane/) → [Youtube Video](https://www.youtube.com/playlist?list=PL85tTROKkZrWyqCcmNCdWajpx05-cTal4) → [More Mantine Components](https://mantine-extensions.vercel.app/) ## Features - Separate `Split.Pane` (content) and `Split.Resizer` (drag handle) architecture - 7 resizer variants: `default`, `filled`, `outline`, `transparent`, `gradient`, `dotted`, `dashed` - Initial sizes in pixels or percentages with min/max constraints - `grow` property to let specific panes expand to fill available space - Horizontal and vertical orientation, including responsive breakpoints - Context-based prop inheritance: resizer props set on `Split` cascade to all children - Per-resizer overrides for full control - Snap points for common pane sizes during drag and keyboard resizing - `autoResizers` mode to automatically insert resizers between panes - `Split.Dynamic` helper to generate panes from a configuration array - Resize lifecycle events (`onResizeStart`, `onResizing`, `onResizeEnd`) on both pane and resizer — fired on drag, keyboard resize, and double-click reset - Custom content inside `Split.Resizer` for drag-affordance icons, labels, or fully bespoke handles - Keyboard accessible: focusable resizer with configurable `step` and `shiftStep` - Container resize tracking with drag ratio preservation ## Installation ```sh npm install @gfazioli/mantine-split-pane ``` or ```sh yarn add @gfazioli/mantine-split-pane ``` After installation import package styles at the root of your application: ```tsx import '@gfazioli/mantine-split-pane/styles.css'; ``` ## Usage ```tsx import { Split } from '@gfazioli/mantine-split-pane'; import { Paper } from '@mantine/core'; function Demo() { return ( <Split> <Split.Pane> <Paper withBorder w="100%" mih="100%"> <h1>Pane 1</h1> </Paper> </Split.Pane> <Split.Resizer /> <Split.Pane> <Paper withBorder> <h1>Pane 2</h1> </Paper> </Split.Pane> </Split> ); } ``` ### Auto Resizers Use the `autoResizers` prop to automatically insert resizers between panes: ```tsx import { Split } from '@gfazioli/mantine-split-pane'; import { Paper } from '@mantine/core'; function Demo() { return ( <Split autoResizers> <Split.Pane> <Paper withBorder w="100%" mih="100%"> <h1>Pane 1</h1> </Paper> </Split.Pane> <Split.Pane> <Paper withBorder> <h1>Pane 2</h1> </Paper> </Split.Pane> <Split.Pane> <Paper withBorder> <h1>Pane 3</h1> </Paper> </Split.Pane> </Split> ); } ``` ### Snap Points Use `snapPoints` and `snapTolerance` to snap a resizer to common pane sizes in pixels while dragging or using the keyboard: ```tsx import { Split } from '@gfazioli/mantine-split-pane'; import { Paper } from '@mantine/core'; function Demo() { return ( <Split autoResizers snapPoints={[200, 400, 600]} snapTolerance={20}> <Split.Pane initialWidth={240}> <Paper withBorder w="100%" mih="100%"> <h1>Pane 1</h1> </Paper> </Split.Pane> <Split.Pane initialWidth={320}> <Paper withBorder w="100%" mih="100%"> <h1>Pane 2</h1> </Paper> </Split.Pane> <Split.Pane grow> <Paper withBorder w="100%" mih="100%"> <h1>Pane 3</h1> </Paper> </Split.Pane> </Split> ); } ``` `snapPoints` and `snapTolerance` are also available on `Split.Resizer` for per-divider overrides. With `autoResizers`, the generated resizers inherit these values from `Split`. ### Dynamic Panes You can also use `Split.Dynamic` to create panes from a configuration array: ```tsx import { Split, PaneConfig } from '@gfazioli/mantine-split-pane'; import { Paper } from '@mantine/core'; function Demo() { const panes: PaneConfig[] = [ { id: 'sidebar', initialWidth: 200, minWidth: 150, content: ( <Paper withBorder w="100%" h="100%"> <h1>Sidebar</h1> </Paper> ), }, { id: 'main', grow: true, content: ( <Paper withBorder w="100%" h="100%"> <h1>Main Content</h1> </Paper> ), }, ]; return ( <Split> {Split.Dynamic({ panes })} </Split> ); } ``` ## Sponsor <div align="center"> [<kbd> <br/> ❤️ If this component has been useful to you or your team, please consider becoming a sponsor <br/> </kbd>](https://github.com/sponsors/gfazioli?o=esc) </div> Your support helps me: - Keep the project actively maintained with timely bug fixes and security updates - Add new features, improve performance, and refine the developer experience - Expand test coverage and documentation for smoother adoption - Ensure long-term sustainability without relying on ad hoc free time - Prioritize community requests and roadmap items that matter most Open source thrives when those who benefit can give back—even a small monthly contribution makes a real difference. Sponsorships help cover maintenance time, infrastructure, and the countless invisible tasks that keep a project healthy. Your help truly matters. 💚 [Become a sponsor](https://github.com/sponsors/gfazioli?o=esc) today and help me keep this project reliable, up-to-date, and growing for everyone. --- https://github.com/user-attachments/assets/2e45af2b-60c7-4cb3-9b9a-6cf0e710af1c --- [![Star History Chart](https://api.star-history.com/svg?repos=gfazioli/mantine-split-pane&type=Timeline)](https://www.star-history.com/#gfazioli/mantine-split-pane&Timeline)