114 lines
3.1 KiB
TypeScript
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();
|