@@ -9,13 +9,13 @@ A responsive, draggable split panel component for [Panel](https://panel.holoviz.
99
1010## Features
1111
12- - ** Draggable divider ** - Resize panels by dragging the divider between them
13- - ** Collapsible panels** - Toggle panels open/closed with optional buttons
12+ - ** Draggable dividers ** - Resize panels by dragging the divider between them
13+ - ** Collapsible panels** - Collapse individual panels with toggle buttons
1414- ** Flexible orientation** - Support for both horizontal and vertical splits
15- - ** Minimum size constraints** - Enforce minimum panel sizes to prevent over-collapse
16- - ** Smooth animations ** - Beautiful transitions when toggling panels
15+ - ** Size constraints** - Enforce minimum and maximum panel sizes
16+ - ** Snap behavior ** - Smart snapping to minimum sizes for better UX
1717- ** Customizable sizes** - Control initial and expanded panel sizes
18- - ** Invertible layout ** - Swap panel positions and button locations
18+ - ** Multi-panel support ** - Create layouts with 2+ panels using ` MultiSplit `
1919
2020## Installation
2121
@@ -43,7 +43,8 @@ pn.extension()
4343split = Split(
4444 pn.pane.Markdown(" ## Left Panel\n Content here" ),
4545 pn.pane.Markdown(" ## Right Panel\n More content" ),
46- sizes = (50 , 50 ), # Equal sizing
46+ sizes = (50 , 50 ), # Equal sizing initially
47+ min_size = 100 , # Minimum 100px for each panel
4748 show_buttons = True
4849)
4950
@@ -75,6 +76,7 @@ split = HSplit(
7576 left_panel,
7677 right_panel,
7778 sizes = (70 , 30 ), # 70% left, 30% right
79+ min_size = 200 , # Minimum 200px for each panel
7880 show_buttons = True
7981)
8082
@@ -96,7 +98,7 @@ split = VSplit(
9698 top_panel,
9799 bottom_panel,
98100 sizes = (60 , 40 ),
99- orientation = " vertical "
101+ min_size = 150
100102)
101103
102104split.servable()
@@ -110,72 +112,90 @@ from panel_splitjs import Split
110112
111113pn.extension()
112114
113- # Start with sidebar collapsed
115+ # Start with right panel collapsed
114116split = Split(
115117 pn.pane.Markdown(" ## Main Content" ),
116118 pn.pane.Markdown(" ## Collapsible Sidebar" ),
117- collapsed = True ,
119+ collapsed = 1 , # 0 for first panel, 1 for second panel, None for not collapsed
118120 expanded_sizes = (65 , 35 ), # When expanded, 65% main, 35% sidebar
119121 show_buttons = True ,
120- min_sizes = (200 , 200 ) # Minimum 200px for each panel
122+ min_size = (200 , 200 ) # Minimum 200px for each panel
121123)
122124
123125# Toggle collapse programmatically
124126button = pn.widgets.Button(name = " Toggle Sidebar" )
125- button.on_click(lambda e : setattr (split, ' collapsed' , not split.collapsed))
127+ def toggle (event ):
128+ split.collapsed = None if split.collapsed == 1 else 1
129+ button.on_click(toggle)
126130
127131pn.Column(button, split).servable()
128132```
129133
130- ### Inverted Layout
134+ ### Multi-Panel Split
131135
132136``` python
133137import panel as pn
134- from panel_splitjs import Split
138+ from panel_splitjs import MultiSplit
135139
136140pn.extension()
137141
138- # Inverted: right panel collapses, button on right side
139- split = Split (
140- pn.pane.Markdown(" ## Secondary Panel" ),
141- pn.pane.Markdown(" ## Main Content " ),
142- invert = True , # Swap layout and button position
143- collapsed = True ,
144- expanded_sizes = ( 35 , 65 ),
145- show_buttons = True
142+ # Create a layout with three panels
143+ multi = MultiSplit (
144+ pn.pane.Markdown(" ## Panel 1 " ),
145+ pn.pane.Markdown(" ## Panel 2 " ),
146+ pn.pane.Markdown( " ## Panel 3 " ),
147+ sizes = ( 30 , 40 , 30 ), # Three panels with custom sizing
148+ min_size = 100 , # Minimum 100px for each panel
149+ orientation = " horizontal "
146150)
147151
148- split .servable()
152+ multi .servable()
149153```
150154
151155## API Reference
152156
153157### Split
154158
155- The main split panel component with full customization options .
159+ The main split panel component for creating two-panel layouts with collapsible functionality .
156160
157161** Parameters:**
158162
159163- ` objects ` (list): Two Panel components to display in the split panels
160- - ` collapsed ` (bool, default=False): Whether the secondary panel is collapsed
161- - ` expanded_sizes ` (tuple, default=(50, 50)): Percentage sizes when expanded (must sum to 100)
162- - ` invert ` (bool, default=False): Swap panel positions and button locations (constant after init)
163- - ` min_sizes ` (tuple, default=(0, 0)): Minimum sizes in pixels for each panel
164- - ` orientation ` (str, default="horizontal"): Either "horizontal" or "vertical"
165- - ` show_buttons ` (bool, default=False): Show collapse/expand toggle buttons
166- - ` sizes ` (tuple, default=(100, 0)): Initial percentage sizes (must sum to 100)
164+ - ` collapsed ` (int | None, default=None): Which panel is collapsed - ` 0 ` for first panel, ` 1 ` for second panel, ` None ` for not collapsed
165+ - ` expanded_sizes ` (tuple, default=(50, 50)): Percentage sizes when both panels are expanded
166+ - ` max_size ` (int | tuple, default=None): Maximum sizes in pixels - single value applies to both panels, tuple for individual sizes
167+ - ` min_size ` (int | tuple, default=0): Minimum sizes in pixels - single value applies to both panels, tuple for individual sizes
168+ - ` orientation ` (str, default="horizontal"): Either ` "horizontal" ` or ` "vertical" `
169+ - ` show_buttons ` (bool, default=True): Show collapse/expand toggle buttons on the divider
170+ - ` sizes ` (tuple, default=(50, 50)): Initial percentage sizes of the panels
171+ - ` snap_size ` (int, default=30): Snap to minimum size at this offset in pixels
172+ - ` step_size ` (int, default=1): Step size in pixels at which panel sizes can be changed
167173
168174### HSplit
169175
170176Horizontal split panel (convenience class).
171177
172- Same parameters as ` Split ` but ` orientation ` is locked to "horizontal".
178+ Same parameters as ` Split ` but ` orientation ` is locked to ` "horizontal" ` .
173179
174180### VSplit
175181
176182Vertical split panel (convenience class).
177183
178- Same parameters as ` Split ` but ` orientation ` is locked to "vertical".
184+ Same parameters as ` Split ` but ` orientation ` is locked to ` "vertical" ` .
185+
186+ ### MultiSplit
187+
188+ Multi-panel split component for creating layouts with three or more panels.
189+
190+ ** Parameters:**
191+
192+ - ` objects ` (list): List of Panel components to display (3 or more)
193+ - ` max_size ` (int | tuple, default=None): Maximum sizes in pixels - single value applies to all panels, tuple for individual sizes
194+ - ` min_size ` (int | tuple, default=100): Minimum sizes in pixels - single value applies to all panels, tuple for individual sizes
195+ - ` orientation ` (str, default="horizontal"): Either ` "horizontal" ` or ` "vertical" `
196+ - ` sizes ` (tuple, default=None): Initial percentage sizes of the panels (length must match number of objects)
197+ - ` snap_size ` (int, default=30): Snap to minimum size at this offset in pixels
198+ - ` step_size ` (int, default=1): Step size in pixels at which panel sizes can be changed
179199
180200## Common Use Cases
181201
@@ -193,10 +213,10 @@ output = pn.Column("# Output Area")
193213split = Split(
194214 chat,
195215 output,
196- collapsed = False ,
216+ collapsed = None , # Both panels visible
197217 expanded_sizes = (50 , 50 ),
198218 show_buttons = True ,
199- min_sizes = (300 , 300 )
219+ min_size = (300 , 300 ) # Minimum 300px for each panel
200220)
201221
202222split.servable()
@@ -221,35 +241,90 @@ visualization = pn.pane.Markdown("## Main Visualization Area")
221241split = Split(
222242 controls,
223243 visualization,
224- collapsed = True ,
244+ collapsed = 0 , # Start with controls collapsed
225245 expanded_sizes = (25 , 75 ),
226246 show_buttons = True ,
227- min_sizes = (250 , 400 )
247+ min_size = (250 , 400 ) # Minimum sizes for each panel
228248)
229249
230250split.servable()
231251```
232252
233- ### Responsive Layout
253+ ### Responsive Layout with Size Constraints
234254
235255``` python
236256import panel as pn
237257from panel_splitjs import Split
238258
239259pn.extension()
240260
241- # Automatically adjust to available space
242261split = Split(
243262 pn.pane.Markdown(" ## Panel 1\n Responsive content" ),
244263 pn.pane.Markdown(" ## Panel 2\n More responsive content" ),
245264 sizes = (50 , 50 ),
246- min_sizes = (200 , 200 ), # Prevent panels from getting too small
265+ min_size = 200 , # Minimum 200px per panel
266+ max_size = 800 , # Maximum 800px per panel
267+ snap_size = 50 , # Snap to min size when within 50px
247268 show_buttons = True
248269)
249270
250271split.servable()
251272```
252273
274+ ### Complex Multi-Panel Layout
275+
276+ ``` python
277+ import panel as pn
278+ from panel_splitjs import MultiSplit
279+
280+ pn.extension()
281+
282+ # Create a four-panel layout
283+ sidebar = pn.Column(" ## Sidebar" , pn.widgets.Select(options = [" A" , " B" , " C" ]))
284+ main = pn.pane.Markdown(" ## Main Content Area" )
285+ detail = pn.pane.Markdown(" ## Detail Panel" )
286+ console = pn.pane.Markdown(" ## Console Output" )
287+
288+ multi = MultiSplit(
289+ sidebar,
290+ main,
291+ detail,
292+ console,
293+ sizes = (15 , 40 , 25 , 20 ), # Custom sizing for each panel
294+ min_size = (150 , 300 , 200 , 150 ), # Individual minimums
295+ orientation = " horizontal"
296+ )
297+
298+ multi.servable()
299+ ```
300+
301+ ### Nested Splits
302+
303+ ``` python
304+ import panel as pn
305+ from panel_splitjs import HSplit, VSplit
306+
307+ pn.extension()
308+
309+ # Create a nested layout: horizontal split with vertical split on right
310+ left = pn.pane.Markdown(" ## Left Panel" )
311+
312+ # Right side has a vertical split
313+ top_right = pn.pane.Markdown(" ## Top Right" )
314+ bottom_right = pn.pane.Markdown(" ## Bottom Right" )
315+ right = VSplit(top_right, bottom_right, sizes = (60 , 40 ))
316+
317+ # Main horizontal split
318+ layout = HSplit(
319+ left,
320+ right,
321+ sizes = (30 , 70 ),
322+ min_size = 200
323+ )
324+
325+ layout.servable()
326+ ```
327+
253328## Development
254329
255330This project is managed by [ pixi] ( https://pixi.sh ) .
0 commit comments