Responsive Sidebar

Collapsible sidebar navigation with state persistence.

Live Demo

Navigation

Source

HTML + JavaScript
<div data-component="app-layout" data-storage-key="app-layout" data-auto-save>
    <div class="sidebar" data-bind-class="sidebarOpen
        ? 'sidebar' : 'sidebar collapsed'">
        <div data-list="navItems">
            <template>
                <div data-bind-class="name === activePage
                    ? 'nav-item active' : 'nav-item'"
                     data-action="selectPage" data-bind="label"></div>
            </template>
        </div>
    </div>
    <div class="main-area">
        <button data-action="toggleSidebar">&#9776;</button>
        <span data-bind="pageTitle"></span>
        <p data-bind="pageContent"></p>
    </div>
</div>

<script>
wildflower.component('app-layout', {
    state: {
        sidebarOpen: true,
        activePage: 'dashboard',
        navItems: [
            { name: 'dashboard', label: 'Dashboard' },
            { name: 'users', label: 'Users' },
            { name: 'settings', label: 'Settings' },
            { name: 'logs', label: 'Logs' }
        ]
    },
    computed: {
        pageTitle() {
            const item = this.navItems.find(n => n.name === this.activePage);
            return item ? item.label : '';
        },
        pageContent() { return 'Content for the ' + this.activePage + ' page.'; }
    },
    toggleSidebar() { this.sidebarOpen = !this.sidebarOpen; },
    selectPage(e, el, { index }) {
        this.activePage = this.navItems[index].name;
    }
});
</script>

Key Points

  • data-bind-class with a ternary toggles the collapsed class, and CSS transition handles the animation
  • data-storage-key + data-auto-save persists sidebar open/closed state and active page to localStorage
  • Nav items rendered from an array, with the active item highlighted via data-bind-class comparison
  • Page content uses computed properties that react to activePage changes