edith003/src/common/registry/ComponentRegistry.ts

114 lines
3.1 KiB
TypeScript

import type { CSSProperties } from 'react';
import type { ComponentDefinition } from './types';
/**
* Centralized registry for all component definitions.
* Singleton pattern ensures a single source of truth.
*/
class ComponentRegistryClass {
private definitions: Map<string, ComponentDefinition> = new Map();
/**
* Register a component definition
* @param definition The component definition to register
* @throws Error if component type is already registered
*/
register(definition: ComponentDefinition): void {
if (this.definitions.has(definition.type)) {
console.warn(`Component type "${definition.type}" is already registered. Overwriting.`);
}
this.definitions.set(definition.type, definition);
}
/**
* Get a component definition by type
* @param type The component type to look up
* @returns The component definition or undefined if not found
*/
get(type: string): ComponentDefinition | undefined {
return this.definitions.get(type);
}
/**
* Check if a component type is registered
* @param type The component type to check
*/
has(type: string): boolean {
return this.definitions.has(type);
}
/**
* Get all registered component definitions
* @returns Array of all component definitions
*/
getAll(): ComponentDefinition[] {
return Array.from(this.definitions.values());
}
/**
* Get component definitions filtered by category
* @param category 'container' or 'leaf'
*/
getByCategory(category: 'container' | 'leaf'): ComponentDefinition[] {
return this.getAll().filter((def) => def.category === category);
}
/**
* Get default styles for a component type
* @param type The component type
* @returns Default styles or empty object if not found
*/
getDefaultStyles(type: string): CSSProperties {
const definition = this.get(type);
return definition?.defaultStyles ?? {};
}
/**
* Get default props for a component type
* @param type The component type
* @returns Default props or empty object if not found
*/
getDefaultProps(type: string): Record<string, any> {
const definition = this.get(type);
return definition?.defaultProps ?? {};
}
/**
* Check if a component type can have children
* @param type The component type
* @returns true if component can have children, false otherwise
*/
canHaveChildren(type: string): boolean {
const definition = this.get(type);
return definition?.canHaveChildren ?? false;
}
/**
* Get icon component for a component type
* @param type The component type
* @returns Icon component or undefined if not found
*/
getIcon(type: string): React.ComponentType<any> | undefined {
const definition = this.get(type);
return definition?.icon;
}
/**
* Get all registered component types
* @returns Array of component type strings
*/
getTypes(): string[] {
return Array.from(this.definitions.keys());
}
/**
* Clear all registered components (useful for testing)
*/
clear(): void {
this.definitions.clear();
}
}
// Export singleton instance
export const ComponentRegistry = new ComponentRegistryClass();