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

122 lines (121 loc) 4.24 kB
import { type ComponentType } from 'react'; /** * Enhances components with Portal functionality by providing the necessary context infrastructure. * * This Higher-Order Component (HOC) wraps any React component with a PortalContextProvider, * enabling the use of Portal and Portal.Anchor components within the component tree. It creates * an isolated portal context that manages the registration, rendering, and lifecycle of all * portal content within the wrapped component and its descendants. * * ### Use Cases * - **Root Application Wrapper**: Enable portal functionality across your entire app * - **Feature Module Isolation**: Create portal contexts for specific features or pages * - **Component Library Integration**: Add portal capabilities to third-party components * - **Modal System Architecture**: Build reusable modal systems with proper context isolation * * ### Key Features * - Creates an isolated portal context scope for the wrapped component * - Manages multiple Portal instances with unique identification and lifecycle * - Provides automatic cleanup and memory management for portal content * - Maintains React component tree structure while enabling DOM location changes * - Memory-optimized with React.memo for performance * * ### Context Scope and Isolation * - Each withPortal wrapper creates its own independent portal context * - Portal components only work within their nearest withPortal ancestor * - Multiple withPortal instances can coexist without interference * - Context isolation prevents portal content from appearing in wrong locations * * @example * ```typescript * // Application-level portal setup * const App = Portal.with(() => { * return ( * <div className="app"> * <Header /> * <Main /> * <Footer /> * // Global portal anchor for modals, tooltips, etc. * <Portal.Anchor className="global-portal-root" /> * </div> * ); * }); * * // Feature-specific portal context * const DashboardPage = Portal.with(() => { * const [showSettings, setShowSettings] = useState(false); * * return ( * <div className="dashboard"> * <Sidebar> * <button onClick={() => setShowSettings(true)}> * Settings * </button> * * {showSettings && ( * <Portal> * <SettingsModal onClose={() => setShowSettings(false)} /> * </Portal> * )} * </Sidebar> * * <MainContent /> * * // Dashboard-specific portal anchor * <Portal.Anchor className="dashboard-modals" /> * </div> * ); * }); * * // Nested portal contexts (each has its own scope) * const ComplexLayout = Portal.with(() => { * return ( * <div className="layout"> * <Header> * <Portal> * <div className="header-notification">Header portal content</div> * </Portal> * </Header> * * <Content> * // Nested portal context for content area * <ContentWithPortals /> * </Content> * * <Portal.Anchor className="header-portals" /> * </div> * ); * }); * * const ContentWithPortals = Portal.with(() => { * return ( * <div> * <Portal> * <div className="content-overlay">Content portal content</div> * </Portal> * * <Portal.Anchor className="content-portals" /> * </div> * ); * }); * * // Wrapping third-party components * import { SomeLibraryComponent } from 'some-library'; * const LibraryWithPortals = Portal.with(SomeLibraryComponent); * * const Usage = () => ( * <LibraryWithPortals someProp="value"> * <Portal> * <CustomOverlay /> * </Portal> * * <Portal.Anchor /> * </LibraryWithPortals> * ); * ``` * * @typeParam Type - The type definition for the wrapped component's props * @param Component - The React component to enhance with Portal context functionality * @returns A memoized component that provides Portal context to its children and can use Portal/Portal.Anchor */ export declare const withPortal: <Type extends object>(Component: ComponentType<Type>) => import("react").MemoExoticComponent<(props: Type) => import("react/jsx-runtime").JSX.Element>;