UNPKG

@hadyfayed/filament-react-wrapper

Version:

Enterprise React integration for Laravel/Filament - Smart asset loading, 90%+ React-PHP function mapping, no-plugin Filament integration

603 lines (591 loc) 17.8 kB
import require$$0 from 'react-dom'; import { j as jsxRuntimeExports } from './state-management-CLPmisQN.js'; import React from 'react'; function _mergeNamespaces(n, m) { for (var i = 0; i < m.length; i++) { const e = m[i]; if (typeof e !== 'string' && !Array.isArray(e)) { for (const k in e) { if (k !== 'default' && !(k in n)) { const d = Object.getOwnPropertyDescriptor(e, k); if (d) { Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: () => e[k] }); } } } } } return Object.freeze(Object.defineProperty(n, Symbol.toStringTag, { value: 'Module' })); } var client$1 = {}; var hasRequiredClient; function requireClient () { if (hasRequiredClient) return client$1; hasRequiredClient = 1; var m = require$$0; if (process.env.NODE_ENV === 'production') { client$1.createRoot = m.createRoot; client$1.hydrateRoot = m.hydrateRoot; } else { var i = m.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; client$1.createRoot = function(c, o) { i.usingClientEntryPoint = true; try { return m.createRoot(c, o); } finally { i.usingClientEntryPoint = false; } }; client$1.hydrateRoot = function(c, h, o) { i.usingClientEntryPoint = true; try { return m.hydrateRoot(c, h, o); } finally { i.usingClientEntryPoint = false; } }; } return client$1; } var clientExports = requireClient(); const client = /*#__PURE__*/_mergeNamespaces({ __proto__: null }, [clientExports]); class ReactErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false }; } static getDerivedStateFromError(error) { return { hasError: true, error }; } componentDidCatch(error, errorInfo) { console.error("React component error:", error, errorInfo); this.props.onError?.(error); } render() { if (this.state.hasError) { return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-4 border border-red-300 rounded-md bg-red-50", children: [ /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-red-800 font-medium", children: "Component Error" }), /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-red-600 text-sm mt-1", children: this.state.error?.message || "An unexpected error occurred" }), /* @__PURE__ */ jsxRuntimeExports.jsx( "button", { onClick: () => this.setState({ hasError: false, error: void 0 }), className: "mt-2 px-3 py-1 bg-red-600 text-white text-sm rounded hover:bg-red-700", children: "Retry" } ) ] }); } return this.props.children; } } const UniversalReactWrapper = React.memo( ({ componentName, componentProps, onDataChange, onError }) => { const componentDef = React.useMemo(() => { return componentRegistry.get(componentName); }, [componentName]); const Component = React.useMemo(() => { if (!componentDef) return null; if (componentDef.isAsync) { return React.lazy( componentDef.component ); } else { return componentDef.component; } }, [componentDef]); const mergedProps = React.useMemo( () => ({ ...componentDef?.defaultProps || {}, ...componentProps, onDataChange }), [componentDef?.defaultProps, componentProps, onDataChange] ); if (!componentDef || !Component) { const error = new Error( `Component "${componentName}" not found in registry` ); onError?.(error); return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-4 border border-yellow-300 rounded-md bg-yellow-50", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-yellow-800", children: [ 'Component "', componentName, '" not found. Available components:', " ", componentRegistry.getComponentNames().join(", ") || "None" ] }) }); } return /* @__PURE__ */ jsxRuntimeExports.jsx(ReactErrorBoundary, { onError, children: /* @__PURE__ */ jsxRuntimeExports.jsx(React.Suspense, { fallback: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Loading..." }), children: /* @__PURE__ */ jsxRuntimeExports.jsx(Component, { ...mergedProps }) }) }); }, (prevProps, nextProps) => { if (prevProps.componentName !== nextProps.componentName) { return false; } try { if (prevProps.componentProps === nextProps.componentProps) { return true; } const prevKeys = Object.keys(prevProps.componentProps || {}); const nextKeys = Object.keys(nextProps.componentProps || {}); if (prevKeys.length !== nextKeys.length) { return false; } if (prevKeys.length < 10) { return JSON.stringify(prevProps.componentProps) === JSON.stringify(nextProps.componentProps); } return prevKeys.every( (key) => prevProps.componentProps[key] === nextProps.componentProps[key] ); } catch { return prevProps.componentProps === nextProps.componentProps; } } ); class UniversalReactRenderer { roots = /* @__PURE__ */ new Map(); containers = /* @__PURE__ */ new Map(); /** * Render a React component in the specified container */ render({ component, props = {}, statePath, containerId, onDataChange, onError }) { try { const container = document.getElementById(containerId); if (!container) { throw new Error(`Container element with ID "${containerId}" not found`); } let root = this.roots.get(containerId); if (!root) { root = clientExports.createRoot(container); this.roots.set(containerId, root); this.containers.set(containerId, container); } const handleDataChange = (data) => { if (onDataChange) { onDataChange(data); } if (statePath && window.workflowDataSync) { window.workflowDataSync(statePath, data); } }; root.render( /* @__PURE__ */ jsxRuntimeExports.jsx( UniversalReactWrapper, { componentName: component, componentProps: props, onDataChange: handleDataChange, onError, statePath } ) ); } catch (error) { console.error("Error rendering React component:", error); onError?.(error); } } /** * Update props for an already rendered component */ updateProps(containerId, newProps) { const root = this.roots.get(containerId); const container = this.containers.get(containerId); if (!root || !container) { console.warn( `No rendered component found for container "${containerId}"` ); return; } const existingData = container.dataset; this.render({ component: existingData.component || "", props: newProps, statePath: existingData.statePath, containerId }); } /** * Unmount a React component */ unmount(containerId) { const root = this.roots.get(containerId); if (root) { root.unmount(); this.roots.delete(containerId); this.containers.delete(containerId); } } /** * Check if a component is rendered in the specified container */ isRendered(containerId) { return this.roots.has(containerId); } /** * Unmount all rendered components */ unmountAll() { for (const [containerId] of this.roots) { this.unmount(containerId); } } /** * Get list of active container IDs */ getActiveContainers() { return Array.from(this.roots.keys()); } /** * Check if a container has an active React component */ hasActiveComponent(containerId) { return this.roots.has(containerId); } } const universalReactRenderer = new UniversalReactRenderer(); if (typeof window !== "undefined") { window.addEventListener("beforeunload", () => { universalReactRenderer.unmountAll(); }); } if (typeof window !== "undefined") { window.universalReactRenderer = universalReactRenderer; } class EventSystem { listeners = /* @__PURE__ */ new Map(); on(event, callback, priority = 10) { if (!this.listeners.has(event)) { this.listeners.set(event, []); } this.listeners.get(event).push({ callback, priority }); this.listeners.get(event).sort((a, b) => b.priority - a.priority); } off(event, callback) { const listeners = this.listeners.get(event); if (listeners) { const index = listeners.findIndex((l) => l.callback === callback); if (index !== -1) { listeners.splice(index, 1); } } } emit(event, data) { const listeners = this.listeners.get(event); if (!listeners) return data; let result = data; for (const listener of listeners) { try { const returned = listener.callback(result); if (returned !== void 0) { result = returned; } } catch (error) { console.error(`Error in event listener for ${event}:`, error); } } return result; } hasListeners(event) { return this.listeners.has(event) && this.listeners.get(event).length > 0; } clear() { this.listeners.clear(); } getListenerCount(event) { if (event) { return this.listeners.get(event)?.length || 0; } return Array.from(this.listeners.values()).reduce( (total, arr) => total + arr.length, 0 ); } } class ReactComponentRegistry { components = /* @__PURE__ */ new Map(); events = new EventSystem(); extensions = /* @__PURE__ */ new Map(); middleware = []; // Component factory for future extensibility // private componentFactory: ComponentFactoryManager = // new ComponentFactoryManager(); /** * Register a React component with enhanced features */ register(definition) { this.events.emit("component:registering", { definition }); if (definition.config?.dependencies) { for (const dep of definition.config.dependencies) { if (!this.has(dep)) { console.warn( `Component ${definition.name} depends on ${dep} which is not registered` ); } } } const isAsyncImport = typeof definition.component === "function" && !(definition.component.prototype && definition.component.prototype.isReactComponent); let processedComponent = definition.component; if (isAsyncImport && definition.isAsync !== false && !definition.isAsync) { console.warn( `Component ${definition.name} appears to be an async import but lazy loading is disabled in bundled mode. Ensure all components are imported synchronously.` ); definition.isAsync = true; } for (const middleware of this.middleware) { const context = { registry: this, hooks: this.createHookManager(), config: definition.config || {}, metadata: definition.metadata || {} }; try { const result = middleware( processedComponent, definition.defaultProps || {}, context ); if (result instanceof Promise) { result.then((comp) => processedComponent = comp).catch((error) => { console.error(`Error in async middleware for ${definition.name}:`, error); }); } else { processedComponent = result; } } catch (error) { console.error(`Error in middleware for ${definition.name}:`, error); } } const processedDefinition = { ...definition, component: processedComponent, isAsync: definition.isAsync, config: { lazy: false, cache: false, ssr: false, preload: false, ...definition.config } }; this.components.set(definition.name, processedDefinition); this.events.emit("component:registered", { definition: processedDefinition }); } /** * Get a registered component by name */ get(name) { const definition = this.components.get(name); if (definition) { this.events.emit("component:accessed", { name, definition }); } return definition; } /** * Create a component instance with processing */ create(name, props = {}) { const definition = this.get(name); if (!definition) { console.error(`Component ${name} not found in registry`); return null; } const mergedProps = { ...definition.defaultProps, ...props }; let component = definition.component; if (definition.config?.middleware) { for (const middleware of definition.config.middleware) { const context = { registry: this, hooks: this.createHookManager(), config: definition.config, metadata: definition.metadata || {} }; if (typeof component === "function" && !component.then && (component.prototype?.isReactComponent || typeof component === "function" && !component.prototype?.isReactComponent)) { component = middleware( component, mergedProps, context ); } } } this.events.emit("component:created", { name, props: mergedProps, component }); if (typeof component === "function" && !component.then && (component.prototype?.isReactComponent || typeof component === "function" && !component.prototype?.isReactComponent)) { return component; } console.error(`Component ${name} is not a valid React component`); return () => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ "Invalid component: ", name ] }); } /** * Register an extension */ registerExtension(name, extension) { this.extensions.set(name, extension); this.events.emit("extension:registered", { name, extension }); } /** * Add global middleware */ addMiddleware(middleware) { this.middleware.push(middleware); } /** * Get all registered components with filtering */ getAll(filter) { if (!filter) { return new Map(this.components); } const filtered = /* @__PURE__ */ new Map(); this.components.forEach((definition, name) => { let include = true; if (filter.category && definition.metadata?.category !== filter.category) { include = false; } if (filter.tag && !definition.metadata?.tags?.includes(filter.tag)) { include = false; } if (filter.name && !filter.name.test(name)) { include = false; } if (include) { filtered.set(name, definition); } }); return filtered; } /** * Check if a component is registered */ has(name) { return this.components.has(name); } /** * Unregister a component */ unregister(name) { if (this.components.has(name)) { this.events.emit("component:unregistering", { name }); const result = this.components.delete(name); this.events.emit("component:unregistered", { name }); return result; } return false; } /** * Clear all registered components */ clear() { this.events.emit("registry:clearing"); this.components.clear(); this.events.emit("registry:cleared"); } /** * Get list of registered component names */ getComponentNames() { return Array.from(this.components.keys()); } /** * Get component statistics */ getStats() { const stats = { totalComponents: this.components.size, categoryCounts: {}, tagCounts: {} }; this.components.forEach((definition) => { const category = definition.metadata?.category || "uncategorized"; stats.categoryCounts[category] = (stats.categoryCounts[category] || 0) + 1; if (definition.metadata?.tags) { for (const tag of definition.metadata.tags) { stats.tagCounts[tag] = (stats.tagCounts[tag] || 0) + 1; } } }); return stats; } /** * Add event listener */ on(event, callback, priority) { this.events.on(event, callback, priority); } /** * Remove event listener */ off(event, callback) { this.events.off(event, callback); } /** * Mount a component to a DOM container (for Blade template compatibility) */ mount(componentName, containerId, props = {}) { try { universalReactRenderer.render({ component: componentName, props, containerId, onDataChange: props.onDataChange, onError: (error) => { console.error(`Error mounting component ${componentName}:`, error); } }); } catch (error) { console.error(`Failed to mount component ${componentName}:`, error); } } /** * Unmount a component from a DOM container */ unmount(containerId) { try { universalReactRenderer.unmount(containerId); } catch (error) { console.error(`Failed to unmount component:`, error); } } /** * Create hook manager for component context */ createHookManager() { return { addHook: (event, callback, priority) => { this.events.on(event, callback, priority); }, removeHook: (event, callback) => { this.events.off(event, callback); }, executeHooks: (event, data) => { return this.events.emit(event, data); } }; } } const componentRegistry = new ReactComponentRegistry(); function registerComponents(definitions) { definitions.forEach((definition) => { componentRegistry.register(definition); }); } export { componentRegistry as a, client as c, registerComponents as r, universalReactRenderer as u }; //# sourceMappingURL=component-system-Bjje-CZe.js.map