Files
nick-doc/05 - Design System/Layouts.md
2026-05-23 20:35:34 +03:30

7.7 KiB

title, tags, created
title tags created
Layouts
design-system
layout
ui
2026-05-23

Layouts

Page-template wrappers in frontend/src/layouts/. Each layout encapsulates a header, optional sidebar, content slot, and footer — pages mount inside one and never re-implement chrome.


1. Layout variants

Layout Used for Header Sidebar Footer
auth-centered/ Sign-in, sign-up, verify, reset-password Logo only none Compact links
auth-split/ Marketing-leaning auth (sign-up with promo panel) Logo only Left visual panel none
dashboard/ Every /dashboard/* route Topbar with user menu + notifications + language + settings Vertical / Mini / Horizontal none
main/ Public marketing pages (shop/, post/, landing) Marketing nav none Full footer

2. Dashboard layout

layouts/dashboard/ is the workhorse. It uses MUI's LayoutSection pattern — slots for header, sidebar, main, footer with media-query-aware responsive behavior.

2.1 Anatomy

┌─────────────────────────────────────────────────────┐
│  TopBar  ─────────────────────────  search  bell ▾ │  ← `header-section`
├─────────┬───────────────────────────────────────────┤
│  Nav    │  Breadcrumbs                              │
│         │  ┌─ Page content (mounted route) ──────┐  │
│  ┌───┐  │  │                                      │  │
│  │ ○ │  │  │                                      │  │
│  └───┘  │  │                                      │  │
│  user   │  │                                      │  │
│  profile│  │                                      │  │
├─────────┴───────────────────────────────────────────┤
│  (optional) Footer slot — unused in dashboard       │
└─────────────────────────────────────────────────────┘

2.2 Sidebar variants

User can switch via the Settings Drawer:

Variant Width Behavior
vertical 280 px Default; icon + label, collapsible groups
mini 88 px Icons only; labels in tooltip on hover
horizontal full-width below header Nav as a horizontal menu — main content below

2.3 Topbar

Contains, left-to-right:

  • Sidebar toggle button (mobile / mini-mode)
  • Logo (mini, shown only when sidebar is collapsed)
  • Search (Cmd+K palette) — optional
  • Language selector (chip with flag)
  • Settings drawer toggle (cog icon)
  • Notifications drawer toggle (bell with unread count badge)
  • Account dropdown (avatar → profile, sign-out)

2.4 Nav configuration

Nav items defined as a tree in a config file (e.g., layouts/dashboard/config-nav-dashboard.ts):

const navData = [
  {
    subheader: 'Overview',
    items: [
      { title: 'Dashboard', path: paths.dashboard.root, icon: ICONS.dashboard },
      { title: 'Chat', path: paths.dashboard.chat, icon: ICONS.chat },
    ],
  },
  {
    subheader: 'Marketplace',
    items: [
      { title: 'Requests', path: paths.dashboard.request.root, icon: ICONS.request,
        roles: ['buyer', 'admin'] },
      { title: 'Templates', path: paths.dashboard.template.root, icon: ICONS.template,
        roles: ['seller', 'admin'] },
      // ...
    ],
  },
  // ...
];

Each items[i] may carry roles: string[] to scope visibility. The nav renderer filters items based on the current user's role before rendering — entries without roles are shown to everyone.

2.5 Breadcrumbs

components/custom-breadcrumbs renders the active route trail plus an optional action button slot (e.g., "+ New Request"). Convention: set via the page component.


3. Auth layouts

3.1 auth-centered/

Single column, centered card. Used by sign-in, password reset, email verification.

┌──────────────────────────────┐
│           Logo               │
│                              │
│   ┌────────────────────┐    │
│   │  Title             │    │
│   │  Form fields...    │    │
│   │  CTA               │    │
│   └────────────────────┘    │
│                              │
│   Tiny footer links          │
└──────────────────────────────┘

3.2 auth-split/

Two-column on md+, single column on small screens. Left = visual / brand panel; right = form.

┌──────────────┬───────────────┐
│              │  Logo         │
│   Visual     │               │
│   panel      │   Form        │
│   (image,    │               │
│    quote,    │   CTA         │
│    benefit)  │               │
│              │   Footer      │
└──────────────┴───────────────┘

Used for sign-up to balance marketing copy with the form.


4. Main (public) layout

layouts/main/ is for unauthenticated visitor pages. Sticky header, then content, then full footer.

Header includes:

  • Logo
  • Top-level nav (Shop, Blog, About)
  • Language switcher
  • "Sign in" / "Sign up" buttons (or "Dashboard" if signed in)

Footer includes:

  • Brand block
  • Sitemap
  • Legal links
  • Social media
  • Newsletter signup (optional)

5. Responsive behavior

Breakpoint xs (<600) sm (≥600) md (≥900) lg (≥1200) xl (≥1536)
Dashboard sidebar drawer overlay drawer overlay mini default full default full default
Auth-split single col single col two col two col two col
Main nav hamburger hamburger inline inline inline
Page padding 16 px 16 px 24 px 32 px 32 px

Implementation note: do NOT add @media rules in components. Use the responsive sx syntax:

<Box sx={{ p: { xs: 2, md: 3, lg: 4 } }} />

6. Sticky elements

  • TopBar uses position: sticky; top: 0; z-index: appBar so it stays on scroll.
  • Action bars on long forms can use the same pattern at bottom (bottom: 0).

7. Skeleton & loading

  • Each dashboard/*/page.tsx can ship a sibling loading.tsx that renders skeleton placeholders matching the final layout.
  • For long-loading sections, use <Suspense fallback={<SkeletonX />}>.

8. Error boundaries

  • App-level error boundary at root layout catches uncaught render errors.
  • Each route segment may ship error.tsx for scoped recovery (e.g., dashboard/shops/error.tsx).
  • Snackbars handle non-fatal API errors.

9. Adding a new layout

  1. Create layouts/<name>/ with index.tsx (default export the layout component).
  2. Slot pattern: accept children; render header + nav + main + (optional) footer.
  3. Reuse components/scrollbar for the main scroll area to keep custom scrollbar styling.
  4. If it's an auth flow, wire it into app/auth/<flow>/layout.tsx.