> ## Documentation Index
> Fetch the complete documentation index at: https://docs.monolex.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# OnIt Rendering & Interaction

> UI generation and event handling systems for the OnIt session viewer

## Rendering Pipeline

The render system transforms parsed OnitSession data into interactive HTML through a hierarchical method structure.

```
┌─────────────────────────────────────────────────┐
│  Render Flow                                    │
├─────────────────────────────────────────────────┤
│                                                 │
│  render()                                       │
│    ↓                                            │
│  renderHeader() + count                         │
│    ↓                                            │
│  sessions.length > 0?                           │
│    ↓              ↓                             │
│  renderSessionList()  renderEmptyMessage()      │
│    ↓                                            │
│  container.innerHTML = combined HTML            │
│    ↓                                            │
│  attachEventListeners()                         │
│                                                 │
└─────────────────────────────────────────────────┘
```

## Render Methods

**Method Inventory (7 total):**

| Method                      | Purpose                     |
| --------------------------- | --------------------------- |
| `render()`                  | Main orchestrator           |
| `renderSessionList()`       | Session accordion container |
| `renderSessionItemHtml()`   | Individual session item     |
| `createStatusIconElement()` | Status icon SVG             |
| `getStatusBgColor()`        | Background color for status |
| `getStatusTextColor()`      | Text color for status       |
| `renderEmptyMessage()`      | Empty state display         |

The base class provides `renderHeader()` and `getViewerStyles()` for consistent UI across all wiki viewers.

## Session Item Structure

Each session renders as an accordion item with status indicators and metadata.

**Visual Layout:**

```
┌─────────────────────────────────────────────────┐
│ [>]  [●]  session-name          14:30  [active] │
│  ↑    ↑         ↑                 ↑        ↑    │
│ arrow dot      name             date    status  │
│                                                 │
│ (collapsed - click to expand)                   │
└─────────────────────────────────────────────────┘
```

**Element Breakdown:**

* **Arrow icon**: 16×16px, rotates 90° when expanded
* **Status dot**: 6×6px circle, color matches status badge
* **Session name**: Flex:1, truncates with ellipsis
* **Date/time**: 11px font, never truncates
* **Status badge**: 10px font, 2px padding, rounded corners

## Status Visualization

Three status types with consistent color coding:

| Status    | Color | RGB                  | Background  | Icon        |
| --------- | ----- | -------------------- | ----------- | ----------- |
| Active    | Green | `rgb(16, 185, 129)`  | 15% opacity | CheckCircle |
| Completed | Blue  | `rgb(59, 130, 246)`  | 15% opacity | CheckCircle |
| Archived  | Gray  | `rgb(107, 114, 128)` | 15% opacity | Package     |

Status is determined automatically:

* **Active**: `modifiedAt` within 24 hours
* **Completed**: In WIP folder, older than 24 hours
* **Archived**: In wiki folder (not WIP)

## Date Formatting

Smart date display based on recency:

**Formatting Logic:**

```
┌─────────────────────────────────────────────────┐
│  Date Display Decision                          │
├─────────────────────────────────────────────────┤
│                                                 │
│  Unknown date?                                  │
│    YES → formatRelativeTime() or ""             │
│    NO  → Check modification time                │
│                                                 │
│  Modified < 24h ago?                            │
│    YES → Show time (HH:MM)                      │
│                                                 │
│  Modified < 48h ago?                            │
│    YES → Show "yesterday"                       │
│                                                 │
│  Modified > 48h ago?                            │
│    YES → Show date (YYYY-MM-DD)                 │
│                                                 │
└─────────────────────────────────────────────────┘
```

**Examples:**

* Modified 2 hours ago: "14:30"
* Modified yesterday: "yesterday"
* Modified 3 days ago: "2025-12-25"

## Event System

Two-layer event handling with base class integration.

### Toggle Listeners

Inherited from WikiBaseViewer, handles WIP/Wiki switching:

**Flow:**

1. User clicks \[WIP] or \[Wiki] button
2. Get `data-mode` attribute
3. Update `isWip` flag
4. Call `refresh()` (reload data + re-render)

**Effect:**

* Changes filesystem path (`wip/onit/` ↔ `wiki/onit/`)
* Loads different session set
* Resets all UI state (accordion expansions lost)

### Accordion Listeners

Handles session expansion/collapse with content loading:

**Flow:**

1. User clicks session header
2. Query `.wiki-accordion-item` wrapper
3. Get `data-doc-path` attribute
4. Call `toggleAccordion()` from base class

**Accordion State Machine:**

```
┌─────────────────────────────────────────────────┐
│  Accordion States                               │
├─────────────────────────────────────────────────┤
│                                                 │
│  CLOSED (initial)                               │
│    ↓ Click header                               │
│  LOADING                                        │
│    ↓ Content loads                              │
│  EXPANDED (content visible)                     │
│    ↓ Click header again                         │
│  COLLAPSED (cached)                             │
│    ↓ Click header again                         │
│  EXPANDED (instant - from cache)                │
│                                                 │
└─────────────────────────────────────────────────┘
```

**Key Features:**

* Content caching: No re-load on re-expand
* Sticky headers: Header sticks during scroll
* Smooth scrolling: `scrollIntoView()` on expand

## Sticky Header Behavior

When accordion expands, its header becomes sticky below the viewer header.

**Calculation:**

```
┌─────────────────────────────────────────────────────────────────────┐
│  STICKY HEADER POSITION CALCULATION                                 │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  1. Find viewer header element                                      │
│     viewerHeader = container.querySelector(".wiki-viewer-header")   │
│                                                                     │
│  2. Calculate sticky offset                                         │
│     stickyTop = viewerHeader ? viewerHeader.offsetHeight : 0        │
│                                                                     │
│  3. Apply sticky positioning                                        │
│     header.position = "sticky"                                      │
│     header.top = stickyTop   (~40px for OnIt)                       │
│                                                                     │
│  Result: Accordion header sticks below viewer header                │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘
```

This keeps the session header visible when scrolling through long content.

## Empty State

Context-aware empty state message based on current mode:

**WIP Mode:**

```
No OnIt sessions found

Create a new session with /niia-onit
```

**Wiki Mode:**

```
No OnIt sessions found

Graduate WIP sessions to archive them here
```

The message guides users toward the appropriate action for each context.

## Refresh Mechanism

Complete data reload and UI re-render:

**Refresh Flow:**

```
┌─────────────────────────────────────────────────────┐
│  REFRESH SEQUENCE                                   │
├─────────────────────────────────────────────────────┤
│                                                     │
│  refresh()                                          │
│       │                                             │
│       ├──► loadSessions()  ─► Reload from FS        │
│       │                                             │
│       └──► render()        ─► Replace entire DOM    │
│                                                     │
└─────────────────────────────────────────────────────┘
```

**State Loss on Refresh:**

* All accordion expansions collapse
* Cached content is discarded
* Scroll position may reset
* Only first session expanded (default)

Trade-off: Simplicity over state preservation (SMPC principle).

## Content Export

The `getContent()` method provides plain text export for clipboard:

**Format:**

```
[2025-12-28 14:30] feature-work (active)
[2025-12-27 10:15] bug-fix (completed)
[unknown 00:00] legacy-topic (completed)
```

Pattern: `[{date} {time}] {sessionName} ({status})`

Separator: Newline (`\n`)

Use cases: Copy to clipboard, export to file

<div style={{ textAlign: 'center', marginTop: '3rem', marginBottom: '2rem', fontSize: '1.5rem', fontWeight: '300', color: '#666' }}>
  THE CENTER

  <div style={{ fontSize: '0.9rem', marginTop: '0.5rem' }}>
    Simple interactions preserve focus on content
  </div>
</div>

<Card title="Technical Credibility" icon="code">
  Uses CSS custom properties for theming. Implements accordion pattern from WikiBaseViewer. Status colors match Tailwind's color palette for consistency. All render methods are synchronous except content loading via IPC.
</Card>
