# Layout System — Xertica UI

The Xertica UI layout system provides centralized state management for the application shell — sidebar, assistant panel, and responsive behavior. It is consumed via a React context hook and must not be replicated with local state.

---

## Overview

The layout is built around a three-column shell:

```
┌──────────────┬─────────────────────────┬──────────────┐
│   Sidebar    │    Main Content Area    │  AI Panel    │
│ (collapsed:  │                         │ (assistant,  │
│   80px)      │  paddingLeft = sidebar  │   optional)  │
│ (expanded:   │                         │              │
│  sidebarWidth│      (Header at top)    │              │
└──────────────┴─────────────────────────┴──────────────┘
```

- **Sidebar** and **AI Panel** are mutually exclusive — opening one closes the other.
- The **main content area** adjusts its `paddingLeft` dynamically based on sidebar state and width.
- **Mobile**: The sidebar overlays content instead of pushing it. The `Header` component provides the toggle trigger.

---

## LayoutContext API

`LayoutContext` is injected by `<LayoutProvider>` which is included inside `<XerticaProvider>`. You never instantiate it directly.

### Hook

```tsx
import { useLayout } from 'xertica-ui/hooks';

const {
  sidebarExpanded,
  setSidebarExpanded,
  toggleSidebar,
  sidebarWidth,
  setSidebarWidth,
  assistenteExpanded,
  setAssistenteExpanded,
  toggleAssistente,
  toggleAssistenteWithTab,
} = useLayout();
```

### Context Properties

| Property                  | Type                      | Default | Description                                                      |
| ------------------------- | ------------------------- | ------- | ---------------------------------------------------------------- |
| `sidebarExpanded`         | `boolean`                 | `false` | Whether the sidebar is currently expanded (persisted in cookies) |
| `setSidebarExpanded`      | `(v: boolean) => void`    | —       | Directly set sidebar expanded state                              |
| `toggleSidebar`           | `() => void`              | —       | Toggle sidebar (auto-closes assistant if open)                   |
| `sidebarWidth`            | `number`                  | `280`   | Expanded sidebar width in pixels                                 |
| `setSidebarWidth`         | `(width: number) => void` | —       | Update the expanded sidebar width globally                       |
| `assistenteExpanded`      | `boolean`                 | `false` | Whether the AI assistant panel is open                           |
| `setAssistenteExpanded`   | `(v: boolean) => void`    | —       | Directly set assistant expanded state                            |
| `toggleAssistente`        | `() => void`              | —       | Toggle assistant (auto-closes sidebar if open)                   |
| `toggleAssistenteWithTab` | `(tab: string) => void`   | —       | Open assistant and navigate to a specific tab                    |
| `isMobile`                | `boolean`                 | `false` | Whether the viewport is currently in mobile mode (< 768px)       |

### Features

- **Persistence**: The `sidebarExpanded` state is automatically saved in a cookie named `sidebar_state`.
- **Shortcuts**: Toggling the sidebar expansion can be done via `Ctrl+B` (Windows/Linux) or `Cmd+B` (macOS).
- **Autonomous Sidebar**: The `Sidebar` component will work even without `LayoutProvider`, although it won't synchronize with other layout-aware components.

---

## Usage Patterns

### Reading Sidebar State in a Content Container

The main content container must offset itself based on the sidebar state. Always use `sidebarWidth` from context — never hardcode pixel values:

```tsx
import { useLayout } from 'xertica-ui/hooks';

function PageContent({ children }) {
  const { sidebarExpanded, sidebarWidth } = useLayout();

  return (
    <div
      style={{
        paddingLeft: sidebarExpanded ? `${sidebarWidth}px` : '80px',
      }}
      className="flex-1 flex flex-col overflow-hidden transition-all duration-300"
    >
      {children}
    </div>
  );
}
```

> **80px** is the fixed collapsed sidebar width. This must not change.

### Full Page Layout Shell

```tsx
import { Sidebar, Header } from 'xertica-ui/layout';
import { useLayout } from 'xertica-ui/hooks';
import { useNavigate, useLocation } from 'react-router-dom';

function AppLayout({ user, onLogout }) {
  const { sidebarExpanded, sidebarWidth, toggleSidebar } = useLayout();
  const navigate = useNavigate();
  const location = useLocation();

  return (
    <div className="h-screen flex bg-muted overflow-hidden relative">
      <Sidebar
        expanded={sidebarExpanded}
        width={sidebarWidth}
        onToggle={toggleSidebar}
        user={user}
        onLogout={onLogout}
        location={location}
        navigate={navigate}
        routes={routes}
      />
      <div
        style={{ paddingLeft: sidebarExpanded ? `${sidebarWidth}px` : '80px' }}
        className="flex-1 flex flex-col overflow-hidden transition-all duration-300"
      >
        <Header title="Dashboard" />
        <main className="flex-1 overflow-y-auto bg-muted p-6">{children}</main>
      </div>
    </div>
  );
}
```

---

## AI Rules

- **State Management** — Never use `useState` to manage sidebar expanded/collapsed state in page components.
- **Never** hardcode `paddingLeft: '280px'` or `pl-64` — use `sidebarWidth` from context.
- **Mobile** — The component automatically handles the `LayoutContext` toggle via the `Header` hamburger icon.
- `sidebarWidth` only affects the **expanded desktop state**. The collapsed state is always `80px`.
- Use `toggleSidebar()` / `toggleAssistente()` — not `setSidebarExpanded(true)` — for user-triggered actions, since the toggle functions handle mutual exclusion.
