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}.jsonFor 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 ID | Category | Description |
|---|---|---|
entity-assets | media | Asset browser with upload, primary image selection |
entity-timeline | display | Timeline event panel with auto-populate |
production-status | workflow | Production pipeline status editor |
markdown-content | display | Rendered markdown body content |
primary-image | media | Hero/primary image with placeholder fallback |
entity-chat | interaction | AI chat panel for conversational editing |
entity-relationships | display | Auto-discovers and renders relationship fields |
entity-workflow-trigger | workflow | Workflow trigger buttons |
File Map
| Area | Path | Purpose |
|---|---|---|
| Types | src/types/layout.ts | All layout-related TypeScript interfaces |
| Registry | src/lib/component-block-registry.ts | Built-in block definitions |
| Tab Hook | src/hooks/useLayoutTabs.ts | Resolves tabs from layout with fallback |
| Layout Hook | src/hooks/useEntityLayout.ts | Loads and merges layout for entity type |
| Renderer | src/components/ComponentBlockRenderer.tsx | Generic block renderer |
| Designer | src/components/LayoutDesigner/ | Layout designer UI components |
| Backend | backend/services/layout_service.py | Layout validation and CRUD |
Widget Resolution
When the system determines which widget to use for a field, it follows this precedence chain:
- Custom layout (saved via Layout Designer) — highest priority
field_config(template frontmatter) — template author’s declaration- Pattern inference — field names ending in
_color→color-picker, etc. - Type inference — schema type → default widget (
string→text,boolean→checkbox)
Field Widget Registry
All available widgets are registered in field-widget-registry.ts. The registry provides:
getAllWidgets()— all builtins + plugin widgetsgetWidgetsByCategory()— grouped by category for the Layout Designer dropdowngetWidgetById()— 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:
- Layout field config (user-set in Layout Designer)
field_configfrom template (template author defaults)- Schema-inferred values (automatic fallback)
Related
- Component Blocks Reference — Complete catalog of built-in UI blocks
- Plugin Iframe Protocol — Plugin block integration details