Getting Started
Introduction
@codeleap/portals is a modern, powerful solution for creating and managing React portals (modals, drawers, bottom sheets, alerts) with an elegant, fluent API. It provides a declarative approach to portal management, allowing you to create everything from simple alerts to complex form dialogs with built-in request/response patterns.
Key Features
- Fluent API Design - Chain methods for clean, readable portal definitions
- Request/Response System - Portals can return data using async/await patterns
- TypeScript Native - Full type safety for parameters and return values
- Automatic Stack Management - Multiple portals work seamlessly together with z-index control
- React Hooks Integration - Control portal state with familiar React patterns
- Multiple Portal Types - Modal, Drawer, BottomSheet, and Alert utilities
- Global Configuration - Customize wrapper components and default behaviors
- Async Parameters - Load data before displaying portals
- Independent Rendering - Flexible rendering options for advanced use cases
Installing the Library
Install @codeleap/portals using your package manager:
bun add @codeleap/portals
# or
npm install @codeleap/portals
# or
yarn add @codeleap/portals
Quick Setup
1. Configure the Global Wrappers (once)
Import and configure at the root of your application:
import { Modal, Drawer, BottomSheet } from '@codeleap/portals'
import { MyModalWrapper } from './components/MyModalWrapper'
import { MyDrawerWrapper } from './components/MyDrawerWrapper'
import { MyBottomSheetWrapper } from './components/MyBottomSheetWrapper'
// Set your custom wrapper components
Modal.WrapperComponent = MyModalWrapper
Drawer.WrapperComponent = MyDrawerWrapper
BottomSheet.WrapperComponent = MyBottomSheetWrapper
// Optional: Configure default transition duration (in milliseconds)
Modal.DEFAULT_TRANSITION_DURATION = 300
Drawer.DEFAULT_TRANSITION_DURATION = 250
BottomSheet.DEFAULT_TRANSITION_DURATION = 200
2. Add the Global Outlet
Add the portal outlet to your main App component:
import { Portal } from '@codeleap/portals'
function App() {
return (
<div>
{/* Your application content */}
<Routes>
{/* Your routes */}
</Routes>
{/* Add this at the end - renders all non-independent portals */}
<Portal.GlobalOutlet />
</div>
)
}
3. Create Your First Modal
The portal instance content will always be rendered inside the configured WrapperComponent:
import { modal } from '@codeleap/portals'
const HelloModal = modal()
.content(() => (
<div>
<h2>Hello World!</h2>
<p>Your first modal is working!</p>
</div>
))
// Open it anywhere in your app
HelloModal.open()
4. Create Other Portal Types
You can create different types of portals using the appropriate factory functions:
import { drawer, bottomSheet, modal } from '@codeleap/portals'
// Drawer (side panel)
const SideDrawer = drawer()
.content(() => <div>Drawer content</div>)
// Bottom Sheet
const SettingsSheet = bottomSheet()
.content(() => <div>Bottom sheet content</div>)
// Modal (centered overlay)
const AlertModal = modal()
.content(() => <div>Modal content</div>)