build-app-layout

star 2.4k

Use this skill for any task involving app layouts — building new layouts, adding sidebars or navigation to existing apps, migrating an existing layout to mui-treasury components, or reviewing/improving layout structure. Trigger whenever the user mentions dashboard layout, sidebar navigation, app shell, header/footer/content structure, collapsible sidebar, drawer navigation, layout with sidebar, or asks to "build a layout", "add a sidebar", "set up the app layout", "review the layout". Also trigger when a mockup or design shows an app with sidebar + header + content regions, even if the user doesn't say "layout" explicitly.

siriwatknp By siriwatknp schedule Updated 4/17/2026

name: build-app-layout description: Use this skill for any task involving app layouts — building new layouts, adding sidebars or navigation to existing apps, migrating an existing layout to mui-treasury components, or reviewing/improving layout structure. Trigger whenever the user mentions dashboard layout, sidebar navigation, app shell, header/footer/content structure, collapsible sidebar, drawer navigation, layout with sidebar, or asks to "build a layout", "add a sidebar", "set up the app layout", "review the layout". Also trigger when a mockup or design shows an app with sidebar + header + content regions, even if the user doesn't say "layout" explicitly.

Installation

Components are installed via the mui-treasury CLI into src/mui-treasury/:

# Layout core (Root, Header, Content, Footer, EdgeSidebar, InsetSidebar, etc.)
npx mui-treasury@latest add layout-core

# Sidebar primitives (SidebarContainer, SidebarMenuButton, SidebarIcon, etc.)
npx mui-treasury@latest add sidebar

After installation, import from:

  • @/mui-treasury/layout/layout-core — layout components
  • @/mui-treasury/components/sidebar — sidebar primitives

Recommended Defaults

Use these as starting values unless the user specifies otherwise.

Collapsible EdgeSidebar

  • collapsedWidth: "52px"
  • SidebarIcon shrinkSize="20px" to center icons in the collapsed sidebar
  • permanentAutoCollapse="lg" to auto-collapse below the lg breakpoint
  • <EdgeSidebarCollapser render={<SidebarRail />} /> as a click-to-collapse trigger — SidebarRail is a pure visual component, EdgeSidebarCollapser injects the collapse onClick
  • Use sidebar primitives for sidebar content — they auto-adapt to collapsed state
  • left/right arrow icons for EdgeSidebarCollapser
  • down arrow icon for CollapsibleIcon

EdgeSidebar Content Structure

Place SidebarContainer in the middle of EdgeSidebarContent so it grows to fill available space and becomes the scrollable area for menus. Static-height content (sidebar header/footer) should be siblings of SidebarContainer:

EdgeSidebarContent
├── Sidebar header (static) — e.g. app switcher, logged-in user, logo
├── SidebarContainer (flex: 1, scrollable) — navigation menus
└── Sidebar footer (static) — e.g. user preferences, settings, ads/banner
  • EdgeSidebarContent uses display: flex; flex-direction: column by default
  • SidebarContainer grows via flex: 1 and handles its own overflow scroll
  • Sidebar header/footer keep their natural height and never scroll
  • Sidebar primitives (SidebarMenuButton, SidebarIcon, etc.) still work in the header/footer areas because they are descendants of EdgeSidebar — but collapse-aware CSS variables (--_collapsed/--_uncollapsed) only work inside SidebarContainer

SidebarMenuButton

  • should use the component prop for polymorphism, e.g. <SidebarMenuButton component="a" href="/dashboard"> or <SidebarMenuButton component={Link} to="/dashboard">

  • MUST be a child of SidebarMenuItem which is a child of SidebarMenuList. Never wrap SidebarMenuButton in a plain div or Box — the list structure (SidebarMenuList > SidebarMenuItem > SidebarMenuButton) is required for proper spacing, collapse behavior, and accessibility

  • Never use consecutive SidebarText siblings inside a SidebarMenuButton. For multi-line text, use a single SidebarText wrapping the content. For two-line text labels, use SidebarGroupText:

    // ❌ Wrong — consecutive SidebarText
    <SidebarMenuButton>
      <Avatar />
      <SidebarText><Typography>siriwatknp</Typography></SidebarText>
      <SidebarText><Typography>admin@acme.com</Typography></SidebarText>
    </SidebarMenuButton>
    
    // ✅ Correct — single SidebarText with SidebarGroupText for 2 lines
    <SidebarMenuButton>
      <Avatar />
      <SidebarText>
        <SidebarGroupText>
          <Typography variant="body2">siriwatknp</Typography>
          <Typography variant="caption">admin@acme.com</Typography>
        </SidebarGroupText>
      </SidebarText>
    </SidebarMenuButton>
    
  • Never place secondary actions (e.g. IconButton, Badge) inside SidebarMenuButton. Use SidebarMenuAction as a sibling:

    // ❌ Wrong — actions inside SidebarMenuButton
    <SidebarMenuItem>
      <SidebarMenuButton>
        <Avatar />
        <SidebarText>siriwatknp</SidebarText>
        <Box sx={{ display: "flex", gap: 0.5 }}>
          <IconButton size="small"><MoreHorizRounded /></IconButton>
          <IconButton size="small"><NotificationsRounded /></IconButton>
        </Box>
      </SidebarMenuButton>
    </SidebarMenuItem>
    
    // ✅ Correct — SidebarMenuAction as sibling
    <SidebarMenuItem>
      <SidebarMenuButton>
        <Avatar />
        <SidebarText>siriwatknp</SidebarText>
      </SidebarMenuButton>
      <SidebarMenuAction>
        <IconButton size="small"><MoreHorizRounded /></IconButton>
        <IconButton size="small"><NotificationsRounded /></IconButton>
      </SidebarMenuAction>
    </SidebarMenuItem>
    
  • Never make SidebarMenuButton non-interactive (e.g. component="div" with cursor: "default"). If the element is not clickable, use SidebarMenuItem directly instead:

    // ❌ Wrong — non-interactive button
    <SidebarMenuButton component="div" sx={{ cursor: "default", "&:hover": { bgcolor: "transparent" } }}>
      <Avatar />
      <SidebarText>siriwatknp</SidebarText>
    </SidebarMenuButton>
    
    // ✅ Correct — use SidebarMenuItem for non-interactive content
    <SidebarMenuItem>
      <Avatar />
      <SidebarText>siriwatknp</SidebarText>
    </SidebarMenuItem>
    
  • SidebarMenuAction must only be used alongside a SidebarMenuButton sibling. If there is no SidebarMenuButton, use a plain IconButton instead

Rules of Thumb

  • Don't use hoverUncollapse with EdgeSidebarRail — they are noy designed to work together and can cause janky behavior

  • Don't use hoverUncollapse with SidebarTooltip — tooltips won't show when the sidebar is collapsed, so the hover state becomes inaccessible

  • It's recommended to have only one SidebarContainer as a direct child of EdgeSidebar — having multiple containers will cause the available space to split evenly, which mostly not the desired behavior.

  • Align icons in the center of the collapsed sidebar with proper shrinkSize on SidebarIcon.

  • Align custom elements like avatar in the center of the collapsed sidebar using negative margins with EdgeSidebar variables (see EdgeSidebar Collapsible Variables guide)

  • On pages that use EdgeDrawerTrigger but have no sidebar, add <EdgeSidebar variant={['permanent', { visibility: 'hidden' }]} /> to hide the trigger — permanent mode auto-hides EdgeDrawerTrigger, and visibility: 'hidden' prevents the sidebar from taking visual space

  • To create a floating sidebar (with margin, border, shadow, rounded corners), never apply these styles directly to EdgeSidebarContent — it breaks the layout. Instead, make EdgeSidebarContent transparent and style a child div:

    <EdgeSidebarContent className="bg-transparent">
      <div className="m-2 border shadow-xl rounded-lg bg-background flex flex-col">
        {sidebar}
      </div>
    </EdgeSidebarContent>
    

Documentation

Read the relevant page based on your needs:

  • Tutorials — Step-by-step lessons to build your first layout. Start here if unfamiliar with the layout system.
  • Reference Guides — Complete API for all layout-core components and sidebar primitives with props tables.
  • Explanation — Architecture decisions: CSS Grid + CSS variables, how collapse works, EdgeSidebar vs InsetSidebar, term mappings.

How-to Guides

Integration:

  • Next.js Integration — Set up layout in App Router with layout.tsx/page.tsx split, MUI Treasury theme

Layout patterns:

Sidebar features:

Demos:

Install via CLI
npx skills add https://github.com/siriwatknp/mui-treasury --skill build-app-layout
Repository Details
star Stars 2,442
call_split Forks 151
navigation Branch main
article Path SKILL.md
More from Creator