Widget Builder Quick Reference
Quick reference guide for developers working with the widget builder system
Widget Builder Quick Reference ๐
Fast reference for common widget builder tasks.
๐ Quick Start
Create a New Widget
import { inject } from '@angular/core';
import { WidgetStorageService } from '@libs-widgets/widget-builder';
const widgetStorage = inject(WidgetStorageService);
const widget = await widgetStorage.createWidget(
'button', // WidgetType
'space-123', // spaceId
'universe-456', // universeId (optional)
'user-789', // userId
{
name: 'My Custom Button',
description: 'A custom button widget',
propertyGroups: [/* ... */],
propertyValues: {/* ... */}
}
);
Load Widgets for a Space
const widgets = await widgetStorage.listWidgets('space-123');
Update a Widget
await widgetStorage.updateWidget(
'widget-123',
{
name: 'Updated Name',
propertyValues: { color: 'blue' }
},
'space-123',
'universe-456'
);
๐จ Property Groups
Define Property Groups
import { PropertyGroup, PropertyDefinition } from '@widgets';
const propertyGroups: PropertyGroup[] = [
{
id: 'appearance',
title: 'Appearance',
icon: 'fa-paint-brush',
expanded: true,
order: 0,
properties: [
{
key: 'color',
label: 'Color',
type: 'string',
controlType: 'color-picker',
getValue: (widget) => widget.propertyValues?.color || '#000000',
setValue: (widget, value) => {
widget.propertyValues = { ...widget.propertyValues, color: value };
return widget;
}
}
]
}
];
Access Property Groups
import { WidgetRegistrySyncService } from '@libs-widgets/widget-builder';
const registrySync = inject(WidgetRegistrySyncService);
// Get property groups for a widget type
const propertyGroups = registrySync.getPropertyGroups('button');
๐ Event System
Emit Widget Saved Event
// Automatically emitted by workspace component
window.dispatchEvent(new CustomEvent('widget-builder:widget-saved', {
detail: { widgetId: 'widget-123' }
}));
Listen for Widget Events
window.addEventListener('widget-builder:widget-saved', (event: CustomEvent) => {
console.log('Widget saved:', event.detail.widgetId);
});
window.addEventListener('widget-builder:widget-published', (event: CustomEvent) => {
console.log('Widget published:', event.detail.widgetId);
});
๐ฆ Widget Registry
Access Widget Registry
import { WidgetMetadataRegistry } from '@widgets';
const registry = inject(WidgetMetadataRegistry);
// Get all widget types
const types = registry.listWidgetTypes();
// Get widget metadata
const metadata = registry.tryGet('button');
// Get widgets by category
const byCategory = registry.getRegistrationsByCategory();
Sync with Registry
import { WidgetRegistryBridgeService } from '@libs-widgets/widget-builder';
const bridge = inject(WidgetRegistryBridgeService);
bridge.syncWidget(widget, moduleDefinition, propertyGroups);
๐พ Storage Patterns
Storage Keys
// Space-scoped widget
`space_${spaceId}_widget_${widgetId}`
// Workspace state (flash persistence)
`widget-builder:workspace:state`
// Current widget tracking
`widget-builder:current-widget`
Storage Service
import { GgStorage } from '@storage-system';
const storage = inject(GgStorage);
// Store widget
await storage.put(`space_${spaceId}_widget_${id}`, widget);
// Retrieve widget
const widget = await storage.get<Widget>(`space_${spaceId}_widget_${id}`);
// List widgets
const keys = await storage.list();
const widgetKeys = keys.filter(k => k.startsWith(`space_${spaceId}_widget_`));
๐ฏ Widget Manager
Refresh Widgets
import { WidgetsManagerService } from '@libs-widgets/widgets-manager';
const manager = inject(WidgetsManagerService);
// Manual refresh
await manager.refresh();
// Access widgets
const widgets = manager.widgets();
const stats = manager.stats();
Search Widgets
const results = manager.searchWidgets({
query: 'button',
category: 'basic',
scope: 'private'
});
๐จ Code Generation
Generate Widget Code
import { WidgetGeneratorService } from '@libs-widgets/widget-builder';
const generator = inject(WidgetGeneratorService);
const result = await generator.generateWidget({
id: 'custom-button',
name: 'Custom Button',
description: 'A custom button widget',
type: 'button',
properties: [/* ... */],
propertyGroups: [/* ... */],
variants: [/* ... */]
});
console.log(result.files.component); // TypeScript
console.log(result.files.template); // HTML
console.log(result.files.styles); // SCSS
๐จ Live Preview
Setup Live Preview
import { WidgetLivePreviewComponent } from '@libs-widgets/widget-builder';
// In template:
<lib-widget-live-preview
[widget]="previewWidget()"
[breakpoint]="previewBreakpoint()"
[zoom]="previewZoom()"
/>
๐งช Common Patterns
Create Widget with Variants
const widget = await widgetStorage.createWidget(
'button',
spaceId,
universeId,
userId,
{
name: 'Multi-Style Button',
variants: [
{
id: 'primary',
name: 'Primary',
description: 'Primary button style',
properties: { color: '#007bff' },
createdAt: new Date(),
updatedAt: new Date()
},
{
id: 'secondary',
name: 'Secondary',
description: 'Secondary button style',
properties: { color: '#6c757d' },
createdAt: new Date(),
updatedAt: new Date()
}
],
defaultVariant: 'primary'
}
);
Add Property Group Dynamically
// In workspace component
addPropertyGroup() {
const newGroup: PropertyGroup = {
id: `group-${Date.now()}`,
title: 'New Group',
icon: 'fa-cog',
expanded: true,
order: this.propertyGroups().length,
properties: []
};
this.propertyGroups.update(groups => [...groups, newGroup]);
}
Flash Persistence Setup
import { effect } from '@angular/core';
constructor() {
// Auto-save on any signal change
effect(() => {
const state = {
widgetName: this.widgetName(),
propertyGroups: this.propertyGroups(),
propertyValues: this.propertyValues(),
// ... other state
};
this.storage.put('widget-builder:workspace:state', state);
});
}
๐ Debugging Tips
Check Widget Registration
const registry = inject(WidgetMetadataRegistry);
console.log('Registered types:', registry.listWidgetTypes());
console.log('Button metadata:', registry.tryGet('button'));
Verify Storage Keys
const storage = inject(GgStorage);
const keys = await storage.list();
console.log('All keys:', keys);
console.log('Widget keys:', keys.filter(k => k.includes('widget')));
Monitor Events
window.addEventListener('widget-builder:widget-saved', (e) => {
console.log('Widget saved event:', e);
});
window.addEventListener('widget-storage:updated', (e) => {
console.log('Storage updated:', e);
});
๐ Type Definitions
Core Types
import {
Widget,
WidgetType,
WidgetVariant,
PropertyGroup,
PropertyDefinition,
WidgetPropertyValues
} from '@libs-widgets/widget-builder';
import {
SpaceWidget,
WidgetSearchCriteria,
WidgetStats
} from '@libs-widgets/widgets-manager';
import {
WidgetRegistration,
WidgetMetadata
} from '@widgets';
๐จ Common Errors & Solutions
Error: "Widget type not registered"
Solution: Ensure widget type is registered in WidgetMetadataRegistry
const registry = inject(WidgetMetadataRegistry);
if (!registry.has('my-widget')) {
console.error('Widget type not registered');
}
Error: "Property groups undefined"
Solution: Always initialize propertyGroups array
const widget = {
// ...
propertyGroups: [], // Always include
propertyValues: {} // Always include
};
Error: "Storage key not found"
Solution: Check space ID and widget ID format
const key = `space_${spaceId}_widget_${widgetId}`;
const exists = await storage.get(key);
if (!exists) {
console.error('Widget not found at key:', key);
}
๐ Related Documentation
Updated: November 15, 2025