/** * LazyComponent - Universal lazy loading wrapper * * Provides consistent Suspense handling for lazy-loaded components * Works in any React environment: Next.js, Vite, Wails, CRA */ 'use client'; import React, { Suspense, ReactNode, ComponentType, lazy } from 'react'; // Default loading spinner export const DefaultLoader = () => (
Loading...
); // Minimal loader for inline components export const InlineLoader = () => ( Loading... ); // Full-screen loader export const FullScreenLoader = () => (

Loading...

); export interface LazyWrapperProps { children: ReactNode; fallback?: ReactNode; } /** * Suspense wrapper with default fallback */ export function LazyWrapper({ children, fallback }: LazyWrapperProps) { return ( }> {children} ); } /** * Create a lazy-loaded component with Suspense wrapper built-in * * @example * ```tsx * const HeavyComponent = createLazyComponent( * () => import('./HeavyComponent'), * * ); * * // Usage - no need to wrap in Suspense * * ``` */ export function createLazyComponent>( importFn: () => Promise<{ default: T }>, fallback?: ReactNode ) { const LazyComponent = lazy(importFn); return function WrappedLazyComponent(props: React.ComponentProps) { return ( }> ); }; } /** * Create a lazy-loaded component from a named export * * @example * ```tsx * const NamedComponent = createLazyNamedComponent( * () => import('./module'), * 'NamedExport', * * ); * ``` */ export function createLazyNamedComponent< T extends Record>, K extends keyof T >( importFn: () => Promise, exportName: K, fallback?: ReactNode ) { const LazyComponent = lazy(() => importFn().then((mod) => ({ default: mod[exportName] })) ); return function WrappedLazyComponent(props: React.ComponentProps) { return ( }> ); }; }