# Panel Layout and Rendering System Architecture in Superfile

> Explore Superfile's panel layout and rendering system architecture. Understand how independent panels are managed and rendered by custom logic utilizing the lipgloss library.

- Repository: [Yorukot/superfile](https://github.com/yorukot/superfile)
- Tags: architecture
- Published: 2026-07-28

---

**Superfile implements a modular terminal UI using independent panels (sidebar, file panels, preview, prompts) rendered by a custom engine built on the lipgloss library, with each panel managed by specialized factory functions in [`spf_renderers.go`](https://github.com/yorukot/superfile/blob/main/spf_renderers.go) and composed through the `rendering.Renderer` type.**

Superfile, the open-source terminal file manager by `yorukot/superfile`, organizes its interface as a collection of specialized panels. The architecture separates layout management from rendering logic, using a custom abstraction layer over the **lipgloss** library to handle borders, truncation, and styling. This design allows independent panel updates while maintaining consistent visual theming across the entire terminal UI.

## Panel Layout Structure

Superfile divides the terminal UI into six distinct panel regions, each with specific dimensions, positioning, and focus behaviors defined in the layout engine.

### Sidebar Panel

The **Sidebar** provides a tree view of directories surrounding the current working directory. It occupies a fixed width on the left side with a height equal to the total UI height. When focused, the border color changes to `SidebarBorderActiveColor` to indicate active selection.

### File Panels

**File Panels** are scrollable regions that list files in selected directories. They occupy the remaining width after the sidebar allocation, with each panel receiving its own width slice calculated via `FilePanels[i].GetWidth()` and `FilePanels[i].GetHeight()` (see validation logic). The currently focused panel draws its cursor using `FilePanelCursorStyle`.

### File Preview Panel

The optional **File Preview Panel** displays content of the file under the cursor. Positioned to the right of the file panels and sharing their height, this panel only renders when `EnableFilePreviewBorder` is true.

### Prompt and Zoxide Modal

The **Prompt** (and **Zoxide**) panel provides modal input for commands, fuzzy-search, or zoxide navigation. This centered overlay occupies a fraction of the UI height with full terminal width, rendered with a distinct border using `ModalBorderActiveColor`.

### Help Menu Overlay

The **Help Menu** lists hotkey shortcuts and actions in a static overlay similar to the Prompt, using the same active border styling.

### Footer Bars

The **Footer Bars** include the Process Bar, Metadata, and Clipboard strips. These horizontal status bars sit at the bottom with a height of one line and full terminal width. The focused bar changes border color via `FooterBorderActiveColor`.

## Rendering Pipeline Architecture

The rendering pipeline centers on the `rendering.Renderer` type defined in [`src/internal/ui/rendering/renderer.go`](https://github.com/yorukot/superfile/blob/main/src/internal/ui/rendering/renderer.go). This abstraction manages how content sections assemble into final terminal output.

### The rendering.Renderer Type

The `Renderer` type acts as the core composition engine. Factory functions in [`src/internal/ui/spf_renderers.go`](https://github.com/yorukot/superfile/blob/main/src/internal/ui/spf_renderers.go)—such as `SidebarRenderer`, `FilePanelRenderer`, and `PromptRenderer`—configure individual renderers with color palettes from `src/internal/common`, border settings, and renderer names used for logging.

### Content Section Management

Panels build their visual output from one or more **content sections** implementing `ContentRenderer`. The `AddSection()` method inserts new sections while automatically adding visual dividers via `sectionDividers`. The final `Render()` method walks each section, stitches them together with dividers, and applies the assembled style.

### Border Configuration and Styling

Border handling uses a `BorderConfig` object that defines which characters constitute the panel border. The `DefaultLipglossBorder()` function in [`spf_renderers.go`](https://github.com/yorukot/superfile/blob/main/spf_renderers.go) supplies a **lipgloss.Border** constructed from the global config. The `Style()` method composes final lipgloss styles from foreground/background colors, border settings, and any user-provided `StyleModifier`s.

### Truncation and Dimension Enforcement

When panel content exceeds allocated height, the renderer truncates lines while preserving ANSI color codes using `AddLineWithCustomTruncate`. The `TruncateHeight` flag (used by prompts) instructs the renderer to shrink output to fit dimensions. The system validates that rendered width and height respect requested dimensions, logging any mismatches.

## Implementation Examples

### Rendering the Directory Sidebar

Create a sidebar renderer using the factory function and populate it with directory entries:

```go
// Create a sidebar renderer with focus = true
sidebarR := ui.SidebarRenderer(totalHeight, sidebarWidth, true)

// Add directory entries
sidebarR.AddLineWithCustomTruncate("Home ▸", rendering.PlainTruncateRight)
sidebarR.AddLineWithCustomTruncate("Documents ▸", rendering.PlainTruncateRight)

// Render and output
sidebarStr := sidebarR.Render()
fmt.Print(sidebarStr)

```

*Source implementation*: [`src/internal/ui/spf_renderers.go`](https://github.com/yorukot/superfile/blob/main/src/internal/ui/spf_renderers.go) (`SidebarRenderer`)

### Building Multi-Panel File Views

Construct multiple file panels side-by-side by calculating widths and rendering each panel separately before concatenation:

```go
// Calculate individual panel width
panelWidth := (totalWidth - sidebarWidth) / 3

panels := make([]*rendering.Renderer, 3)
for i := 0; i < 3; i++ {
    focused := i == focusedIdx // only one is focused
    panels[i] = ui.FilePanelRenderer(totalHeight, panelWidth, focused)
    
    // Populate with file names
    panels[i].AddLineWithCustomTruncate("file1.txt", rendering.PlainTruncateRight)
    panels[i].AddLineWithCustomTruncate("file2.go", rendering.PlainTruncateRight)
}

// Render side-by-side
var lineBuilder strings.Builder
for lineIdx := 0; lineIdx < totalHeight; lineIdx++ {
    for _, p := range panels {
        lines := strings.Split(p.Render(), "\n")
        lineBuilder.WriteString(lines[lineIdx])
    }
    lineBuilder.WriteByte('\n')
}
fmt.Print(lineBuilder.String())

```

*Source implementation*: [`src/internal/ui/spf_renderers.go`](https://github.com/yorukot/superfile/blob/main/src/internal/ui/spf_renderers.go) (`FilePanelRenderer`) and [`src/internal/ui/rendering/renderer.go`](https://github.com/yorukot/superfile/blob/main/src/internal/ui/rendering/renderer.go) (`Render`)

### Displaying Command Prompts

Modal prompts use the `PromptRenderer` with specific height constraints:

```go
promptR := ui.PromptRenderer(10, totalWidth) // 10 lines tall
promptR.AddLineWithCustomTruncate("Enter command: ", rendering.PlainTruncateRight)
promptStr := promptR.Render()
fmt.Print(promptStr)

```

*Source implementation*: [`src/internal/ui/spf_renderers.go`](https://github.com/yorukot/superfile/blob/main/src/internal/ui/spf_renderers.go) (`PromptRenderer`)

## Key Source Files and Responsibilities

The modular architecture distributes responsibilities across these source files:

- **[`src/internal/ui/spf_renderers.go`](https://github.com/yorukot/superfile/blob/main/src/internal/ui/spf_renderers.go)** – Factory functions (`SidebarRenderer`, `FilePanelRenderer`, `PromptRenderer`) that configure `rendering.Renderer` instances for each panel type
- **[`src/internal/ui/rendering/renderer.go`](https://github.com/yorukot/superfile/blob/main/src/internal/ui/rendering/renderer.go)** – Core `Renderer` implementation handling section management, border configuration, truncation, and style composition
- **[`src/internal/ui/rendering/renderer_core.go`](https://github.com/yorukot/superfile/blob/main/src/internal/ui/rendering/renderer_core.go)** – Helper methods (`AddLines`, `AddSection`, `Render`) operating on internal content sections and enforcing size constraints
- **[`src/internal/ui/rendering/border.go`](https://github.com/yorukot/superfile/blob/main/src/internal/ui/rendering/border.go)** – `BorderConfig` definition and border-drawing utilities
- **[`src/internal/ui/rendering/content_renderer.go`](https://github.com/yorukot/superfile/blob/main/src/internal/ui/rendering/content_renderer.go)** – Text content rendering inside panels, handling line wrapping and custom truncate styles
- **[`src/internal/ui/filepanel/model.go`](https://github.com/yorukot/superfile/blob/main/src/internal/ui/filepanel/model.go)** – Model for single file panels including cursor handling and selection logic
- **[`src/internal/ui/sidebar/model.go`](https://github.com/yorukot/superfile/blob/main/src/internal/ui/sidebar/model.go)** – Directory sidebar model with navigation and current location highlighting
- **[`src/internal/ui/preview/model.go`](https://github.com/yorukot/superfile/blob/main/src/internal/ui/preview/model.go)** – Optional file preview panel model
- **[`src/internal/ui/prompt/model.go`](https://github.com/yorukot/superfile/blob/main/src/internal/ui/prompt/model.go)** – Modal command input model including zoxide integration
- **[`src/internal/ui/helpmenu/model.go`](https://github.com/yorukot/superfile/blob/main/src/internal/ui/helpmenu/model.go)** – Static help menu overlay model
- **`src/internal/ui/footer/*`** – Models for process bar, metadata, and clipboard footers
- **`src/internal/common/*`** – Central color definitions and configuration values referenced by renderers
- **[`src/cmd/main.go`](https://github.com/yorukot/superfile/blob/main/src/cmd/main.go)** – Main UI orchestration: creates panel models, computes dimensions, and concatenates rendered strings each frame

## Summary

- Superfile uses six specialized panel types (Sidebar, File Panels, Preview, Prompt, Help Menu, Footers) with distinct sizing and focus behaviors.
- The rendering engine in [`spf_renderers.go`](https://github.com/yorukot/superfile/blob/main/spf_renderers.go) provides factory functions that configure `rendering.Renderer` instances with lipgloss-based styling.
- Content sections assemble via `AddSection()`, with automatic divider insertion and height truncation preserving ANSI codes.
- Border colors indicate focus state through configurable variables like `SidebarBorderActiveColor` and `FilePanelCursorStyle`.
- The main controller in [`src/cmd/main.go`](https://github.com/yorukot/superfile/blob/main/src/cmd/main.go) coordinates panel models, dimension calculations, and frame output each render cycle.

## Frequently Asked Questions

### How does Superfile indicate which panel currently has focus?

Superfile uses border color changes to indicate focus. When a panel gains focus, its border renders with specific active colors such as `SidebarBorderActiveColor` for the sidebar or `FilePanelCursorStyle` for file panels. Footer bars similarly switch to `FooterBorderActiveColor` when selected.

### What terminal styling library does Superfile use for rendering?

Superfile builds its rendering system on top of **lipgloss**, a Go library for terminal styling. The custom `rendering.Renderer` type in [`src/internal/ui/rendering/renderer.go`](https://github.com/yorukot/superfile/blob/main/src/internal/ui/rendering/renderer.go) wraps lipgloss functionality to handle borders, color palettes from `src/internal/common`, and ANSI-aware text truncation.

### How are panel dimensions calculated and validated in Superfile?

Panel dimensions derive from terminal size queries, with the sidebar taking fixed width and file panels dividing remaining space. The layout engine tracks dimensions via `FilePanels[i].GetWidth()` and `FilePanels[i].GetHeight()` methods. The renderer validates output dimensions against allocations, logging mismatches when content exceeds available space.

### Where does the main UI orchestration logic reside in Superfile?

The primary UI controller lives in **[`src/cmd/main.go`](https://github.com/yorukot/superfile/blob/main/src/cmd/main.go)**. This file creates the layout structure holding panel models, queries terminal dimensions, invokes each panel's `Render()` method, and concatenates the resulting strings for single-frame terminal output.