DeveloperLayout System Architecture

Layout System Architecture

SBAI-84 Phase 3 — Unified Layout System: Component Blocks, Configurable Tabs & Layout-Driven View Pages

The Layout Designer is a full page composer that drives entity edit and view pages from JSON layout definitions. Layouts are stored at _Templates/Layouts/{entity_type}.json and define field sections, component blocks, tabs, and view configuration.

Overview

Layouts determine how entity edit and view pages are rendered. Instead of hardcoded page layouts, each entity type has a JSON layout definition that controls:

  • Field sections — Groups of form fields with ordering, visibility, and collapse defaults
  • Component block sections — Reusable UI widgets (asset browser, timeline, chat, etc.)
  • Tab configuration — Which tabs appear on entity edit pages and in what order
  • View configuration — Whether the entity view page is layout-driven or uses the legacy hand-coded page

Layout File Location

Layouts are stored as JSON files:

_Templates/Layouts/{entity_type}.json

For example: _Templates/Layouts/Character.json, _Templates/Layouts/Location.json

Key Schema Types

EntityLayout

interface EntityLayout {
  entity_type: string;
  sections: LayoutSection[];
  tabs?: LayoutTab[];
  view_config?: LayoutViewConfig;
}

LayoutSection

interface LayoutSection {
  id: string;
  title?: string;
  columns?: number;
  collapsed_default?: boolean;
  fields?: Array<{ name: string; widget?: string }>;
  component?: string;
  component_config?: Record<string, unknown>;
  component_source?: 'builtin' | string;
}

LayoutTab

interface LayoutTab {
  id: string;
  label: string;
  icon?: string;
  source: 'builtin' | 'plugin';
  plugin_id?: string;
}

Component Block Registry

8 built-in blocks registered in src/lib/component-block-registry.ts:

Block IDCategoryDescription
entity-assetsmediaAsset browser with upload, primary image selection
entity-timelinedisplayTimeline event panel with auto-populate
production-statusworkflowProduction pipeline status editor
markdown-contentdisplayRendered markdown body content
primary-imagemediaHero/primary image with placeholder fallback
entity-chatinteractionAI chat panel for conversational editing
entity-relationshipsdisplayAuto-discovers and renders relationship fields
entity-workflow-triggerworkflowWorkflow trigger buttons

File Map

AreaPathPurpose
Typessrc/types/layout.tsAll layout-related TypeScript interfaces
Registrysrc/lib/component-block-registry.tsBuilt-in block definitions
Tab Hooksrc/hooks/useLayoutTabs.tsResolves tabs from layout with fallback
Layout Hooksrc/hooks/useEntityLayout.tsLoads and merges layout for entity type
Renderersrc/components/ComponentBlockRenderer.tsxGeneric block renderer
Designersrc/components/LayoutDesigner/Layout designer UI components
Backendbackend/services/layout_service.pyLayout validation and CRUD

Widget Resolution

When the system determines which widget to use for a field, it follows this precedence chain:

  1. Custom layout (saved via Layout Designer) — highest priority
  2. field_config (template frontmatter) — template author’s declaration
  3. Pattern inference — field names ending in _colorcolor-picker, etc.
  4. Type inference — schema type → default widget (stringtext, booleancheckbox)

Field Widget Registry

All available widgets are registered in field-widget-registry.ts. The registry provides:

  • getAllWidgets() — all builtins + plugin widgets
  • getWidgetsByCategory() — grouped by category for the Layout Designer dropdown
  • getWidgetById() — lookup by widget ID

The Layout Designer’s field configuration panel reads from this registry to populate the widget type dropdown, organized by category: text, number, selection, date, color, entity, array, media, document, and plugin.

field_config Integration

When auto-layout.ts generates a default layout, it reads schema.field_config and merges widget configuration into each field’s layout definition. This means template authors can control widget rendering without using the Layout Designer at all.

The merge order:

  1. Layout field config (user-set in Layout Designer)
  2. field_config from template (template author defaults)
  3. Schema-inferred values (automatic fallback)