Panel Material UI 0.8.0 just released adds .collapsed functionality to the MenuList.
Code
pip install panel panel-material-ui
"""
🎯 Panel Material UI MenuList - Collapsed Parameter Demo
Showcasing how `collapsed=True` creates a compact, icon-only navigation menu!
Perfect for space-constrained sidebars that need to stay functional.
"""
import panel as pn
import panel_material_ui as pmui
import param
pn.extension()
class MenuDemo(pn.viewable.Viewer):
"""Interactive demo showing MenuList collapsed parameter"""
collapsed = param.Boolean(default=True, doc="Whether menu is collapsed")
selected_item = param.Dict(default={}, doc="Currently selected menu item")
# Content for each menu section
CONTENT = {
'🏠 Home': '🏠 **Welcome Home!**\n\nThis is your main dashboard overview.',
'Welcome': '👋 **Welcome Page**\n\nGet started with our platform.',
'Quick Start': '🚀 **Quick Start Guide**\n\nLearn the basics in 5 minutes.',
'📊 Analytics': '📊 **Analytics Dashboard**\n\nView your data insights and metrics.',
'⚙️ Settings': '⚙️ **Settings Panel**\n\nConfigure your preferences.',
'👤 Profile': '👤 **User Profile**\n\nManage your account information.',
}
def __init__(self, **params):
super().__init__(**params)
# Create menu items
self._items = [
{
'label': '🏠 Home',
'icon': 'home',
'secondary': 'Dashboard overview',
'items': [
{'label': 'Welcome', 'icon': 'waving_hand'},
{'label': 'Quick Start', 'icon': 'rocket_launch'},
]
},
{
'label': '📊 Analytics',
'icon': 'analytics',
'secondary': 'Data insights',
},
{
'label': '⚙️ Settings',
'icon': 'settings',
'secondary': 'Configuration',
},
{
'label': '👤 Profile',
'icon': 'account_circle',
'secondary': 'User account',
},
]
# Create toggle button (hamburger menu pattern with ToggleIcon)
self._toggle_button = pmui.ToggleIcon.from_param(
self.param.collapsed,
name="",
icon='menu_open',
active_icon='menu',
description='Toggle menu collapse',
color='primary',
)
self._menu = pmui.MenuList(
items=self._items,
collapsed=self.param.collapsed,
active=0,
color='primary',
dense=True,
expanded=[0]
)
self._menu.link(self, value='selected_item')
# Create content pane (static with reactive content)
self._content_pane = pmui.Container(
pmui.Paper(
pn.pane.Markdown(
self._get_content,
sizing_mode='stretch_width'
),
sizing_mode='stretch_width'
),
sx={'padding': '30px', 'borderRadius': '12px', 'minHeight': '400px'},
sizing_mode='stretch_both'
)
# Build layout with dynamic sidebar
self._sidebar = pmui.Column(
self._get_title,
self._menu,
pn.VSpacer(),
self._toggle_button,
sizing_mode='stretch_height',
# width=self._get_sidebar_width,
styles={'backgroundColor': '#f5f5f5', 'padding': '10px'},
)
self._layout = pmui.Row(
self._sidebar,
self._content_pane,
sizing_mode='stretch_both'
)
@param.depends('collapsed')
def _get_title(self):
"""Show title only when menu is expanded"""
if self.collapsed:
return ''
return '**✨ Navigation**'
@param.depends('selected_item')
def _get_content(self):
"""Get content based on selected menu item"""
if not self.selected_item:
return self.CONTENT.get('🏠 Home', 'Select a menu item')
label = self.selected_item.get('label', '')
return self.CONTENT.get(label, f'**{label}**\n\nContent coming soon...')
def __panel__(self):
return self._layout
# Create and serve the app
if pn.state.served:
MenuDemo().servable()
panel serve app.py --dev