Collapsed MenuList

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
1 Like