### Install Dependencies Source: https://github.com/beautyfree/react-portalslots/blob/main/CONTRIBUTING.md Installs project dependencies using pnpm. Ensure npm is installed before running this command. ```shell pnpm i ``` -------------------------------- ### Install react-portalslots using npm, pnpm, yarn, or bun Source: https://github.com/beautyfree/react-portalslots/blob/main/README.md This snippet shows the different package manager commands to install the react-portalslots library. It covers npm, pnpm, yarn, and bun, ensuring compatibility with various project setups. ```bash npm install react-portalslots # or pnpm add react-portalslots # or yarn add react-portalslots # or bun add react-portalslots ``` -------------------------------- ### Traditional React Layout Without Portal Slots (Prop Drilling Example) Source: https://github.com/beautyfree/react-portalslots/blob/main/README.md Illustrates the limitations of traditional React approaches by showcasing prop drilling. This example defines a Layout component that accepts header and footer content as props, highlighting how components deep within the tree must have their UI elements lifted up, leading to coupling and complexity. ```tsx import React from 'react'; type LayoutProps = { header?: React.ReactNode; footer?: React.ReactNode; children: React.ReactNode; }; function Layout({ header, footer, children }: LayoutProps) { return (
{header}
{children}
); } export function App() { // Content that wants to render into the header/footer must be lifted up here // from deep components, causing prop drilling and tight coupling. return ( Save} footer={© 2025} > ); } function SomeToolbar() { // Cannot push content into the header without threading callbacks/state // through multiple layers or using a global store (which is brittle). return null; } ``` -------------------------------- ### Conventional Commit Message Example Source: https://github.com/beautyfree/react-portalslots/blob/main/CONTRIBUTING.md An example of a commit message following the Conventional Commits specification, specifying a feature addition to the components module. ```text feat(components): add new prop to the avatar component ``` -------------------------------- ### PortalSlotsProvider API Usage Source: https://github.com/beautyfree/react-portalslots/blob/main/README.md Shows the basic implementation of the PortalSlotsProvider, which is a required context provider that must wrap the application or the part of the application where portal slots will be used. It's a simple, declarative setup. ```tsx ``` -------------------------------- ### Basic Usage of react-portalslots with Provider, Slots, and Portals Source: https://github.com/beautyfree/react-portalslots/blob/main/README.md Demonstrates the fundamental usage of react-portalslots. It shows how to set up the PortalSlotsProvider, define named slots (e.g., 'header', 'footer') using PortalSlot, and render content into these slots from different parts of the application. This example illustrates the core pattern of decoupling UI rendering. ```tsx import { PortalSlotsProvider, PortalSlot } from 'react-portalslots'; const HeaderPortal = PortalSlot('header'); const FooterPortal = PortalSlot('footer'); function Layout({ children }: { children: React.ReactNode }) { return (
{children}
); } export function App() { return ( {/* These can live anywhere in the tree */} © 2025 {/* App content */}
Dashboard
); } ``` -------------------------------- ### Setup PortalSlotsProvider in React App Source: https://context7.com/beautyfree/react-portalslots/llms.txt The PortalSlotsProvider acts as a context provider for the portal system. It must wrap your application or the relevant part of the component tree where portals will be utilized. This ensures that a single registry instance is available to track all portal slots and their associated DOM containers. ```tsx import { PortalSlotsProvider } from 'react-portalslots'; function App() { return ( ); } export default App; ``` -------------------------------- ### PortalSlot Factory Function API Usage Source: https://github.com/beautyfree/react-portalslots/blob/main/README.md Demonstrates how to use the `PortalSlot` factory function to create named slots and their corresponding components. This includes creating a slot container (`Slot`) and a portal component that renders content into that slot. It highlights the creation of a 'header' slot as an example. ```tsx const HeaderPortal = PortalSlot('header'); // Use the slot in your layout // Render content into the slot from anywhere ``` -------------------------------- ### Error Boundary Integration with Portals in React Source: https://context7.com/beautyfree/react-portalslots/llms.txt This example demonstrates how to integrate portals with error boundaries in a React application using TypeScript. It shows how to handle rendering failures gracefully within portal components. The code defines a reusable ErrorBoundary component and a BuggyComponent that can simulate errors. It requires 'react-portalslots' and 'react'. ```tsx import { PortalSlotsProvider, PortalSlot } from 'react-portalslots'; import { Component, type ReactNode, type ErrorInfo } from 'react'; const NotificationPortal = PortalSlot('notifications'); class ErrorBoundary extends Component< { children: ReactNode; fallback: ReactNode }, { hasError: boolean; error: Error | null } > { constructor(props: { children: ReactNode; fallback: ReactNode }) { super(props); this.state = { hasError: false, error: null }; } static getDerivedStateFromError(error: Error) { return { hasError: true, error }; } componentDidCatch(error: Error, errorInfo: ErrorInfo) { console.error('Error boundary caught:', error, errorInfo); } render() { if (this.state.hasError) { return this.props.fallback; } return this.props.children; } } function Layout({ children }: { children: ReactNode }) { return (
{children}
); } function BuggyComponent({ shouldThrow }: { shouldThrow: boolean }) { if (shouldThrow) { throw new Error('Component crashed!'); } return (
Component working fine
); } function App() { const [shouldThrow, setShouldThrow] = React.useState(false); return (
An error occurred. Portal still works!
} >
); } export default App; ``` -------------------------------- ### Project Build and Check Scripts Source: https://github.com/beautyfree/react-portalslots/blob/main/CONTRIBUTING.md Scripts for building the project for production, performing type checks, and running tests with Jest. ```shell pnpm build ``` ```shell pnpm check ``` ```shell pnpm test ``` -------------------------------- ### PortalSlotsProvider Source: https://github.com/beautyfree/react-portalslots/blob/main/README.md The context provider that must wrap your entire application to enable the portal slots functionality. ```APIDOC ## PortalSlotsProvider ### Description Context provider that must wrap your application. ### Usage ```tsx import { PortalSlotsProvider } from 'react-portalslots'; ``` ``` -------------------------------- ### Multi-Page Layout with React Portal Slots Source: https://context7.com/beautyfree/react-portalslots/llms.txt Demonstrates how different pages can render content into shared layout slots (header, footer) without prop drilling. It uses react-router-dom for routing and defines layout slots using PortalSlot. The content for these slots is provided within page components. ```tsx import { PortalSlotsProvider, PortalSlot } from 'react-portalslots'; import { BrowserRouter, Routes, Route, Link } from 'react-router-dom'; const HeaderPortal = PortalSlot('header'); const FooterPortal = PortalSlot('footer'); function Layout({ children }: { children: React.ReactNode }) { return (
{children}
); } function HomePage() { return (

Home

Welcome to Home Page

© 2025 Home Page

); } function SettingsPage() { const [saved, setSaved] = React.useState(false); return (

Settings

Settings Page

Last saved: {saved ? 'Just now' : 'Never'}

); } function App() { return ( } /> } /> ); } export default App; ``` -------------------------------- ### PortalSlot Factory Source: https://github.com/beautyfree/react-portalslots/blob/main/README.md A factory function that creates a pair of components for a named slot: a Slot component and a Portal component. ```APIDOC ## PortalSlot(name?: string) ### Description Factory function that creates a pair of components for a named slot. - **PortalSlot.Slot**: The slot container where content will be rendered. - **PortalSlot**: Portal component that renders content into the slot. ### Usage ```tsx import { PortalSlot } from 'react-portalslots'; const HeaderPortal = PortalSlot('header'); // Use the slot in your layout // Render content into the slot from anywhere ``` ``` -------------------------------- ### Conditional Rendering with React Portal Slots Source: https://context7.com/beautyfree/react-portalslots/llms.txt Illustrates conditional portal rendering and supports multiple portal instances targeting the same slot. It demonstrates how portal content can be dynamically shown or hidden based on component state. The key takeaway is that only the slot container needs to be present in the DOM for portals to render. ```tsx import { PortalSlotsProvider, PortalSlot } from 'react-portalslots'; const ToolbarPortal = PortalSlot('toolbar'); function Layout({ children }: { children: React.ReactNode }) { return (
{children}
); } function Editor() { const [isEditing, setIsEditing] = React.useState(false); const [hasChanges, setHasChanges] = React.useState(false); return (
{/* Conditionally render portal content */} {isEditing && ( )} {!isEditing && ( )} {/* Multiple portal instances can exist */} {hasChanges && ( Unsaved changes )}