Widget System Architecture - Master Plan
Comprehensive architecture defining Core UI Widgets vs Custom Widgets and Widget-to-Module conversion
ποΈ Widget System Architecture - Master Plan
Last Updated: November 17, 2025
Status: π― MASTER PLAN
Purpose: Define widget system architecture and widget-to-module conversion strategy
π― EXECUTIVE SUMMARY
The Core Question
"How do widgets and modules work together in our platform?"
The Answer
Widgets and modules serve different but complementary purposes:
π§© MODULES (Building Blocks) = Complete Features with Logic + State + Routing
βββ Contain multiple widgets
βββ Have their own state management
βββ Can communicate via ActionRegistry
βββ Follow BrowserModuleContract
βββ Example: sidebar-nav, top-nav, footer modules
π¨ WIDGETS (UI Components) = Pure Presentation + Basic Interaction
βββ Reusable UI elements
βββ No business logic (only presentation)
βββ Configured via inputs/outputs
βββ Live inside modules
βββ Example: button, input, card, panel
π ARCHITECTURAL HIERARCHY
The Complete Stack
π UNIVERSE (Top Level)
βββ Has Grid System (modular-universe)
βββ Each Section = Module Slot
βββ π§© STRUCTURAL MODULES (navigation, layout containers)
β βββ Sidebar Navigation Module
β βββ Top Navigation Module
β βββ Footer Module
β
βββ π§© FEATURE MODULES (complete functionality)
β βββ User Management Module
β βββ E-commerce Cart Module
β βββ Content Management Module
β
βββ π§© PAGE MODULES (content pages built with editor-web-lib)
βββ Contains Custom Widgets
βββ π¨ CUSTOM WIDGETS (built in widget-builder)
β βββ User Profile Card
β βββ Product Showcase
β βββ Feature Section
β βββ Built from β CORE UI WIDGETS β
β
βββ π¨ CORE UI WIDGETS (from ux-ui-* libraries)
βββ ux-ui-core: button, input, card, chip
βββ ux-ui-extended: menu, panel, portal
βββ ux-ui-feedback: toast, dialog, modal
βββ ux-ui-forms: checkbox, select, range
π¨ WIDGET SYSTEM ARCHITECTURE
1. Core UI Widgets (Foundation Layer)
Purpose: Atomic, reusable UI components with NO business logic
Location: libs/libs-ui/ux-ui-* libraries
Characteristics:
- β Pure presentation components
- β Highly configurable via inputs
- β Multiple variants (themes, sizes, states)
- β Zero business logic
- β Standalone Angular components
- β NO state management (StateLESS)
- β NO routing
- β NO data fetching
Example - Button Widget:
@Component({
selector: 'ux-button',
standalone: true,
template: `<button [class]="buttonClasses()">{{ label() }}</button>`
})
export class UxButtonComponent {
label = input<string>('Click me');
variant = input<'primary' | 'secondary' | 'ghost'>('primary');
size = input<'sm' | 'md' | 'lg'>('md');
disabled = input<boolean>(false);
onClick = output<MouseEvent>();
// Computed styles based on inputs
buttonClasses = computed(() => {
return `btn btn-${this.variant()} btn-${this.size()}`;
});
}
Core UI Widget Libraries:
libs/libs-ui/
βββ ux-ui-core/ # Buttons, inputs, cards, chips, icons
βββ ux-ui-extended/ # Menus, panels, portals, context-menu
βββ ux-ui-feedback/ # Toasts, dialogs, modals, alerts
βββ ux-ui-forms/ # Checkboxes, selects, ranges, switches
2. Custom Widgets (Composition Layer)
Purpose: Composed widgets combining Core UI Widgets for specific use cases
Location: Created in widget-builder, stored in widgets-manager
Characteristics:
- β Composition of Core UI Widgets
- β Specific use case (e.g., "Hero Section", "User Profile Card")
- β Has visual designer (grid-based layout)
- β Property Groups for configuration
- β Variants for different contexts
- β Can include Singularity flows for interactivity
- β Still NO complex business logic
- β NO state management (receives data via inputs)
Example - User Profile Card Widget:
// Generated by widget-builder
@Component({
selector: 'custom-user-profile-card',
standalone: true,
imports: [UxButtonComponent, UxChipComponent, UxCardComponent],
template: `
<ux-card variant="elevated">
<img [src]="avatarUrl()" />
<h3>{{ userName() }}</h3>
<p>{{ userBio() }}</p>
<ux-chip [label]="userRole()" />
<ux-button
label="View Profile"
(onClick)="onViewProfile.emit($event)" />
</ux-card>
`
})
export class CustomUserProfileCardWidget {
// Properties from property groups
avatarUrl = input.required<string>();
userName = input.required<string>();
userBio = input<string>('');
userRole = input<string>('User');
// Events
onViewProfile = output<void>();
}
Custom Widget Structure:
Custom Widget
βββ Grid Layout (defined in visual designer)
βββ Core UI Widgets (placed in grid)
βββ Property Groups (configuration interface)
βββ Variants (different styles/configurations)
βββ Singularity Flows (optional interactivity)
π§© MODULE SYSTEM ARCHITECTURE
What is a Module?
A module = Complete feature with logic, state, and UI
Key Difference from Widgets:
WIDGET: Data In β Render UI β Events Out
MODULE: Complete Feature + State + Logic + Routes + API
Module Characteristics
- β Implements BrowserModuleContract
- β Has manifest (ModuleManifest)
- β Can have routes
- β Has state management (uses storage-system)
- β Can communicate via ActionRegistry
- β Contains multiple widgets
- β Has business logic
- β Can fetch data
Module Types
type ModuleType =
// STRUCTURAL MODULES (layout/navigation)
| 'navigation' // TopNav, Sidebar, Footer
| 'layout' // Grid containers, sections
// FEATURE MODULES (complete functionality)
| 'feature' // Cart, Auth, Search, CRM
| 'data' // Data providers, API integrations
// CONTENT MODULES
| 'page' // Content pages (built with editor-web-lib)
// LOGIC MODULES
| 'flow' // Singularity logic flows
// WIDGET MODULES
| 'widget'; // β οΈ When widgets need to become modules
π WIDGET-TO-MODULE CONVERSION STRATEGY
When Should a Widget Become a Module?
Keep as Widget if:
- β Pure presentation
- β No state management needed
- β No routing needed
- β No complex business logic
- β Just needs data in/events out
Convert to Module if:
- β οΈ Needs internal state management
- β οΈ Needs to communicate with other modules
- β οΈ Needs routing
- β οΈ Needs to fetch data
- β οΈ Has complex business logic
- β οΈ Needs to be discoverable in module registry
Conversion Process
Step 1: Identify the Need
User creates "Shopping Cart" widget
β Realizes it needs to:
- Store cart state
- Sync with backend
- Communicate with checkout module
- Have its own routes (/cart, /cart/checkout)
β Time to convert to module!
Step 2: Conversion Tool (Widget-to-Module Generator)
Location: libs/libs-widgets/widget-builder (new feature)
Process:
User clicks "Convert to Module" in widget-builder
System generates:
modules/custom-modules/<widget-name>/ βββ src/ β βββ lib/ β β βββ components/ β β β βββ <widget-name>.component.ts # Original widget β β βββ services/ β β β βββ <widget-name>.service.ts # State management β β βββ <widget-name>.manifest.ts β β βββ <widget-name>.module.ts # Module wrapper β βββ index.ts βββ project.json βββ tsconfig.json βββ README.mdModule manifest includes:
{ id: 'custom-<widget-name>', type: 'widget', // Indicates it's a widget-based module embeddableComponents: [ { id: '<widget-name>', componentType: WidgetComponent, category: 'widget' } ], publicActions: { // Generated from widget events } }
Step 3: Module Registration
- Module registers with ModuleRegistryService
- Becomes discoverable in modular-universe
- Can be placed in grid sections
- Can communicate via ActionRegistry
π― REVISED WIDGET SYSTEM COMPONENTS
1. Widget Gallery (widget-showcase/widget-gallery)
Purpose: Browse and demo CUSTOM widgets only
URL: /widgets/gallery
Features:
- β Browse user-created custom widgets
- β Filter by category/tags
- β Preview functionality
- β Quick access to edit in widget-builder
- β Does NOT show Core UI Widgets (those are in Widget Guide)
2. Widget Guide (widget-showcase/widget-guide)
Purpose: Documentation and variant creation for CORE UI WIDGETS
URL: /widgets/guide
Features:
- β Browse all Core UI Widgets (from ux-ui-* libraries)
- β Interactive demos for each widget
- β Variant Creator (key feature!)
- β Usage examples and API reference
- β Copy code snippets
Variant Creator Flow:
- User selects Core UI Widget (e.g., button)
- Opens variant creator (widget-demo component)
- Adjusts properties (size, color, style)
- Names variant (e.g., "CTA Button - Blue")
- System generates variant config:
{ id: 'cta-button-blue-v1', baseWidget: 'ux-button', properties: { variant: 'primary', size: 'lg', styles: { background: '#3b82f6' } } } - Variant saved to storage-system
- Variant appears in widget-builder component palette
3. Widget Builder (widget-builder)
Purpose: Create custom widgets using Core UI Widgets
URL: /widgets/builder
Redesigned Architecture:
A. Three-Panel Layout
ββββββββββββββββ¬βββββββββββββββββββββββ¬βββββββββββββββ
β β β β
β SIDEBAR β MAIN CANVAS β LIVE PANEL β
β β β β
β (Compact) β (Grid Designer) β (Preview + β
β β β Config) β
β β β β
β - Navigator β Modes: β - Live β
β - Component β β’ Design β Preview β
β Palette β β’ Property Bind β - Property β
β - Quick β β’ Flow Attach β Editor β
β Stats β β’ Preview β - Variants β
β β β - Code Gen β
β β β β
β Collapsible β β Collapsible β
ββββββββββββββββ΄βββββββββββββββββββββββ΄βββββββββββββββ
B. Mode-Based Canvas (Inspired by modular-universe)
type WidgetBuilderMode =
| 'design' // Grid-based visual designer
| 'property-bind' // Connect properties to components
| 'flow-attach' // Attach Singularity flows
| 'preview'; // Live preview with test data
Design Mode:
- Empty canvas with grid overlay
- Drag Core UI Widgets from palette
- Position in grid cells
- Resize and align
- Similar to modular-universe grid-canvas
Property Bind Mode:
- Select widget in canvas
- Map property groups to widget inputs
- Create computed properties
- Set default values
Flow Attach Mode:
- Select widget in canvas
- Attach Singularity flows to events
- Configure flow parameters
- Test flows
Preview Mode:
- Live widget preview
- Test with sample data
- Responsive breakpoints
- Variant switching
C. Component Palette (Enhanced Sidebar)
Structure:
βββββββββββββββββββββββ
β π§© WIDGET BUILDER β
βββββββββββββββββββββββ
β π Quick Stats β
β β’ 9 Property Groups β
β β’ 3 Variants β
β β’ 2 Flows Attached β
βββββββββββββββββββββββ
β π¨ Component Paletteβ
β β
β π¦ Core UI Widgets β
β ββ Basics β
β β ββ Button (5) β β Shows variant count
β β ββ Input (3) β
β β ββ Card (4) β
β ββ Forms β
β β ββ Checkbox β
β β ββ Select β
β ββ Feedback β
β ββ Toast β
β ββ Dialog β
β β
β ποΈ Custom Widgets β
β ββ My Widgets (3) β
β β
β β‘ Singularity β
β ββ Available Flows β
βββββββββββββββββββββββ
β π§ Quick Navigation β
β β’ Properties β β
β β’ Variants β β
β β’ Flows β β
β β’ Code β β
βββββββββββββββββββββββ
Key Improvements:
- β Grouped by category
- β Shows variant count
- β Quick navigation to tabs
- β Collapsible sections
- β Search/filter
- β Drag-and-drop to canvas
D. Live Panel (Always Visible)
Combines preview + configuration
ββββββββββββββββββββββββ
β π¬ LIVE PREVIEW β
ββββββββββββββββββββββββ
β ββββββββββββββββββββ β
β β β β
β β Widget renders β β
β β here in β β
β β real-time β β
β β β β
β ββββββββββββββββββββ β
β Breakpoint: π± π» π₯οΈ β
ββββββββββββββββββββββββ
β βοΈ CONFIGURATION β
ββββββββββββββββββββββββ
β Tabs: [Props][Vars] β
β β
β Active Property: β
β β’ Name: User Name β
β β’ Type: string β
β β’ Default: "" β
β β’ Required: β β
ββββββββββββββββββββββββ
β π Quick Info β
β β’ Total Props: 9 β
β β’ Total Variants: 3 β
β β’ Last Saved: 2m ago β
ββββββββββββββββββββββββ
Benefits:
- β No need for separate preview tab
- β See changes in real-time
- β Configure while previewing
- β Context-aware (shows selected component's properties)
πΎ FLASH PERSISTENCE STRATEGY
Complete State to Persist
interface WidgetBuilderWorkspaceState {
// Widget definition
widgetId: string;
widgetName: string;
widgetType: CoreWidgetType;
widgetDescription: string;
// Design
gridLayout: GridLayout;
components: DesignElement[];
// Configuration
propertyGroups: PropertyGroup[];
propertyValues: WidgetPropertyValues;
variants: WidgetVariant[];
flows: FlowBinding[];
// UI State (CRITICAL - currently missing!)
uiState: {
activePanel: 'design' | 'properties' | 'variants' | 'code' | 'preview';
activeMode: WidgetBuilderMode;
sidebarCollapsed: boolean;
livePanelCollapsed: boolean;
expandedSections: string[];
selectedComponentId: string | null;
activeVariantId: string | null;
codeViewMode: 'component' | 'template' | 'styles' | 'all';
previewBreakpoint: 'mobile' | 'tablet' | 'desktop';
};
// Metadata
lastSaved: number;
lastModified: number;
autoSaveEnabled: boolean;
}
Storage Keys
// Current widget workspace
`widget-builder:workspace:${widgetId}`
// UI preferences (global)
`widget-builder:ui-preferences:${userId}`
// Recent widgets
`widget-builder:recent-widgets:${userId}`
// Auto-save backup
`widget-builder:autosave:${widgetId}`
Flash Persistence Implementation
// In widget-builder-workspace.component.ts
import { GgStorage } from '@storage-system';
export class WidgetBuilderWorkspaceComponent {
private storage = inject(GgStorage);
// Auto-save effect
private autoSaveEffect = effect(() => {
const state: WidgetBuilderWorkspaceState = {
widgetId: this.widgetId(),
widgetName: this.widgetName(),
// ... all state
uiState: {
activePanel: this.activePanel(),
activeMode: this.canvasMode(),
// ... all UI state
},
lastSaved: Date.now()
};
// Flash persistence - saves immediately
this.storage.set(`widget-builder:workspace:${this.widgetId()}`, state);
});
// Load state on init
async ngOnInit() {
const widgetId = this.route.snapshot.params['widgetId'];
if (widgetId) {
const state = await this.storage.get<WidgetBuilderWorkspaceState>(
`widget-builder:workspace:${widgetId}`
);
if (state) {
// Restore complete state
this.widgetName.set(state.widgetName);
this.activePanel.set(state.uiState.activePanel); // β RESTORE UI STATE!
this.canvasMode.set(state.uiState.activeMode);
// ... restore everything
}
}
}
}
π― IMPLEMENTATION ROADMAP
Phase 1: Core UI Widget Separation (Week 1)
- Move Core UI Widget demos to Widget Guide
- Remove Core UI Widgets from Widget Gallery
- Implement variant creator in widget-demo
- Connect variants to storage-system
Phase 2: Widget Builder Redesign (Week 2-3)
- Implement three-panel layout
- Add mode-based canvas system
- Create grid-based visual designer
- Redesign sidebar with component palette
- Implement live panel (preview + config)
Phase 3: Flash Persistence (Week 3)
- Add complete UI state to persistence
- Implement auto-save with UI state
- Add restore functionality
- Test cross-tab synchronization
Phase 4: Widget-to-Module Conversion (Week 4)
- Design conversion UI
- Implement module generator
- Create module scaffold
- Add to module registry
- Document workflow
Phase 5: Integration & Polish (Week 5)
- Integrate with modular-universe
- Test end-to-end workflow
- Performance optimization
- Documentation
- Training materials
π¨ KEY DESIGN PRINCIPLES
1. Separation of Concerns
Core UI Widgets β Basic building blocks (ux-ui-*)
Custom Widgets β Composed for specific use cases (widget-builder)
Modules β Complete features with logic (modules/)
2. Progressive Enhancement
Start Simple β Use Core UI Widget variants
Need More β Create Custom Widget in builder
Complex Logic β Convert to Module
3. Reusability First
Everything is reusable at every level:
- Core UI Widgets have variants
- Custom Widgets are templates
- Modules are self-contained
4. AI-Trainable Architecture
Clear patterns at every level make AI training effective:
- Core UI Widgets: Learn from existing components
- Custom Widgets: Learn from user creations
- Modules: Learn from module manifests
π RELATED DOCUMENTATION
- Module Creation Guide
- Modular Universe Master Plan
- Widget Builder UX Enhancement Plan
- Storage System Documentation
Status: π― Ready for Implementation
Next Steps: Begin Phase 1 - Core UI Widget Separation