Initial commit: nick docs
This commit is contained in:
217
05 - Design System/Layouts.md
Normal file
217
05 - Design System/Layouts.md
Normal file
@@ -0,0 +1,217 @@
|
||||
---
|
||||
title: Layouts
|
||||
tags: [design-system, layout, ui]
|
||||
created: 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`):
|
||||
|
||||
```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:
|
||||
|
||||
```tsx
|
||||
<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`.
|
||||
|
||||
---
|
||||
|
||||
## 10. Related
|
||||
|
||||
- [[Design System Overview]] · [[Theme Configuration]] · [[Components]]
|
||||
- [[Frontend Architecture]] — where layouts sit in the tree
|
||||
- [[Roles & Personas]] — role-driven nav filtering
|
||||
- [[Settings & Theming]] — layout variant switcher
|
||||
Reference in New Issue
Block a user