UNPKG

@memberjunction/ng-react

Version:

Angular components for hosting React components in MemberJunction applications

237 lines (236 loc) 8.94 kB
/** * @fileoverview Angular component that hosts React components with proper memory management. * Provides a bridge between Angular and React ecosystems in MemberJunction applications. * @module @memberjunction/ng-react */ import { EventEmitter, ElementRef, AfterViewInit, OnDestroy, ChangeDetectorRef } from '@angular/core'; import { ComponentSpec, ComponentStyles } from '@memberjunction/interactive-component-types'; import { ReactBridgeService } from '../services/react-bridge.service'; import { AngularAdapterService } from '../services/angular-adapter.service'; import { CompositeKey } from '@memberjunction/core'; import { MJNotificationService } from '@memberjunction/ng-notifications'; import * as i0 from "@angular/core"; /** * Event emitted by React components */ export interface ReactComponentEvent { type: string; payload: any; } /** * State change event emitted when component state updates */ export interface StateChangeEvent { path: string; value: any; } /** * User settings changed event emitted when component saves user preferences */ export interface UserSettingsChangedEvent { settings: Record<string, any>; componentName?: string; timestamp: Date; } /** * Angular component that hosts React components with proper memory management. * This component provides a bridge between Angular and React, allowing React components * to be used seamlessly within Angular applications. */ export declare class MJReactComponent implements AfterViewInit, OnDestroy { private reactBridge; private adapter; private cdr; private notificationService; private _component; /** * The component specification to render. * When this changes after initialization, the component will be reinitialized * to load and render the new specification. */ set component(value: ComponentSpec); get component(): ComponentSpec; /** * Controls verbose logging for component lifecycle and operations. * Note: This does NOT control which React build (dev/prod) is loaded. * To control React builds, use ReactDebugConfig.setDebugMode() at app startup. */ enableLogging: boolean; useComponentManager: boolean; private _utilities; set utilities(value: any); get utilities(): any; private _styles?; set styles(value: Partial<ComponentStyles> | undefined); get styles(): Partial<ComponentStyles>; private _savedUserSettings; set savedUserSettings(value: any); get savedUserSettings(): any; stateChange: EventEmitter<StateChangeEvent>; componentEvent: EventEmitter<ReactComponentEvent>; refreshData: EventEmitter<void>; openEntityRecord: EventEmitter<{ entityName: string; key: CompositeKey; }>; userSettingsChanged: EventEmitter<UserSettingsChangedEvent>; container: ElementRef<HTMLDivElement>; private reactRootId; private compiledComponent; private loadedDependencies; private destroyed$; private currentCallbacks; isInitialized: boolean; private isRendering; private pendingRender; private isDestroying; private componentId; private componentVersion; hasError: boolean; /** * Public property containing the fully resolved component specification. * This includes all external code fetched from registries, allowing consumers * to inspect the complete resolved specification including dependencies. * Only populated after successful component initialization. */ resolvedComponentSpec: ComponentSpec | null; constructor(reactBridge: ReactBridgeService, adapter: AngularAdapterService, cdr: ChangeDetectorRef, notificationService: MJNotificationService); ngAfterViewInit(): Promise<void>; ngOnDestroy(): void; /** * Reinitialize the component when the input spec changes. * Cleans up the current component and initializes with the new spec. */ private reinitializeComponent; /** * Initialize the React component */ private initializeComponent; /** * Generate a hash from component code for versioning * Uses a simple hash function that's fast and sufficient for version differentiation */ private generateComponentHash; /** * Resolve components using the runtime's resolver */ private resolveComponentsWithVersion; /** * NEW: Load component using unified ComponentManager - MUCH SIMPLER! */ private loadComponentWithManager; /** * Register all components in the hierarchy * @deprecated Use loadComponentWithManager() instead */ private registerComponentHierarchy; /** * Post-process resolved spec to ensure all components show their true registry source. * This enriches the spec for UI display purposes to show where components actually came from. * Applied to all resolved specs so any consumer of this wrapper benefits. */ private enrichSpecWithRegistryInfo; /** * Render the React component */ private renderComponent; /** * Create callbacks for the React component */ private createCallbacks; /** * Handle React component errors */ private handleReactError; /** * Handle onSaveUserSettings from components * This implements the SavedUserSettings pattern */ private handleSaveUserSettings; /** * Clean up resources */ private cleanup; /** * Public method to refresh the component * @deprecated Components manage their own state and data now */ refresh(): void; /** * Public method to update state programmatically * @param path - State path to update * @param value - New value * @deprecated Components manage their own state now */ updateState(path: string, value: any): void; /** * Gets the current data state of the component * Used by AI agents to understand what data is currently displayed * @returns The current data state, or undefined if not implemented */ getCurrentDataState(): any; /** * Gets the history of data state changes in the component * @returns Array of timestamped state snapshots, or empty array if not implemented */ getDataStateHistory(): Array<{ timestamp: Date; state: any; }>; /** * Validates the current state of the component * @returns true if valid, false or validation errors otherwise */ validate(): boolean | { valid: boolean; errors?: string[]; }; /** * Checks if the component has unsaved changes * @returns true if dirty, false otherwise */ isDirty(): boolean; /** * Resets the component to its initial state */ reset(): void; /** * Scrolls to a specific element or position within the component * @param target - Element selector, element reference, or scroll options */ scrollTo(target: string | HTMLElement | { top?: number; left?: number; }): void; /** * Sets focus to a specific element within the component * @param target - Element selector or element reference */ focus(target?: string | HTMLElement): void; /** * Invokes a custom method on the component * @param methodName - Name of the method to invoke * @param args - Arguments to pass to the method * @returns The result of the method call, or undefined if method doesn't exist */ invokeMethod(methodName: string, ...args: any[]): any; /** * Checks if a method is available on the component * @param methodName - Name of the method to check * @returns true if the method exists */ hasMethod(methodName: string): boolean; /** * Print the component content * Uses component's print method if available, otherwise uses window.print() */ print(): void; /** * Force clear component registries * Used by Component Studio for fresh loads * This is a static method that can be called without a component instance */ static forceClearRegistries(): void; static ɵfac: i0.ɵɵFactoryDeclaration<MJReactComponent, never>; static ɵcmp: i0.ɵɵComponentDeclaration<MJReactComponent, "mj-react-component", never, { "component": { "alias": "component"; "required": false; }; "enableLogging": { "alias": "enableLogging"; "required": false; }; "useComponentManager": { "alias": "useComponentManager"; "required": false; }; "utilities": { "alias": "utilities"; "required": false; }; "styles": { "alias": "styles"; "required": false; }; "savedUserSettings": { "alias": "savedUserSettings"; "required": false; }; }, { "stateChange": "stateChange"; "componentEvent": "componentEvent"; "refreshData": "refreshData"; "openEntityRecord": "openEntityRecord"; "userSettingsChanged": "userSettingsChanged"; }, never, never, false, never>; }