UNPKG

@winglet/react-utils

Version:

React utility library providing custom hooks, higher-order components (HOCs), and utility functions to enhance React application development with improved reusability and functionality

72 lines (71 loc) 3.39 kB
import { type ForwardRefExoticComponent, type PropsWithoutRef, type ReactNode, type RefAttributes } from 'react'; import type { Dictionary } from '../../@aileron/declare'; /** * Wraps a forwardRef component with error boundary protection while preserving ref forwarding. * * This specialized Higher-Order Component (HOC) is designed specifically for components created * with React.forwardRef. It provides the same error boundary protection as withErrorBoundary * while maintaining the ability to forward refs to the underlying DOM elements or component * instances. This is crucial for components that need direct DOM access or imperative APIs. * * ### Use Cases * - **Form Input Components**: Protect form fields while allowing focus/blur control * - **Custom UI Libraries**: Wrap library components that expose imperative APIs * - **Animation Components**: Protect animated elements while allowing direct manipulation * - **Focus Management**: Maintain focus control in error-prone interactive components * * ### Key Features * - Preserves ref forwarding functionality from the original forwardRef component * - Catches all JavaScript errors in the component tree below it * - Maintains type safety for both props and ref types * - Allows custom fallback UI for better user experience * - Compatible with all forwardRef patterns and use cases * * ### Differences from withErrorBoundary * - Specifically designed for forwardRef components * - Maintains proper TypeScript typing for forwarded refs * - Handles the complexity of wrapping forwardRef components correctly * * @example * ```typescript * // Original forwardRef component * const CustomInput = forwardRef<HTMLInputElement, InputProps>((props, ref) => { * return <input {...props} ref={ref} className="custom-input" />; * }); * * // Wrap with error boundary while preserving ref forwarding * const SafeCustomInput = withErrorBoundaryForwardRef( * CustomInput, * <div>Input component failed to load</div> * ); * * // Usage - ref forwarding still works * const FormComponent = () => { * const inputRef = useRef<HTMLInputElement>(null); * * const focusInput = () => { * inputRef.current?.focus(); // This still works! * }; * * return ( * <div> * <SafeCustomInput ref={inputRef} placeholder="Enter text" /> * <button onClick={focusInput}>Focus Input</button> * </div> * ); * }; * * // Complex component with imperative API * const VideoPlayer = forwardRef<VideoPlayerHandle, VideoProps>((props, ref) => { * // Component implementation... * }); * const SafeVideoPlayer = withErrorBoundaryForwardRef(VideoPlayer); * ``` * * @typeParam Props - The type definition for the component's props * @typeParam Ref - The type of the ref being forwarded to the component * @param Component - The forwardRef component to wrap with error boundary protection * @param fallback - Optional custom fallback JSX to display when an error occurs. If not provided, uses default error message * @returns A new forwardRef component that renders the original component with error boundary protection */ export declare const withErrorBoundaryForwardRef: <Props extends Dictionary, Ref>(Component: ForwardRefExoticComponent<Props & RefAttributes<Ref>>, fallback?: ReactNode) => ForwardRefExoticComponent<PropsWithoutRef<Props> & RefAttributes<Ref>>;