Quick Reference
Quick reference for all portal methods, properties, and patterns.
Factory Functions
import { modal, drawer, bottomSheet } from '@codeleap/portals'
// Create portals
const MyModal = modal()
const MyDrawer = drawer()
const MyBottomSheet = bottomSheet()
// With ID
const UserModal = modal({ id: 'USER_MODAL' })
// With configuration
const ConfiguredModal = modal({
id: 'CONFIGURED',
initialParams: { theme: 'dark' },
startsOpen: false,
independent: false,
rendersWhenHidden: false,
resetParamsOnClose: true,
transitionDuration: 300,
metadata: { category: 'user' }
})
Core Methods
// Define content (required)
MyModal.content((props) => <div>Content</div>)
// Configure wrapper properties
MyModal.props({ title: 'Title', style: ['modal'] })
// Dynamic props
MyModal.props((params) => ({ title: `Editing ${params.name}` }))
// Open portal
MyModal.open()
MyModal.open({ userId: '123' })
// Close portal
MyModal.close()
// Toggle visibility
MyModal.toggle()
// Request with promise
const result = await MyModal.request({ param: 'value' })
// Update parameters
MyModal.setParams({ theme: 'dark' })
MyModal.setParams((prev) => ({ count: prev.count + 1 }))
// Reset parameters
MyModal.resetParams()
// Get parameters
const params = MyModal.getParams()
// Lifecycle hooks
MyModal.onOpen((portal) => console.log('Opened!'))
MyModal.onClose((portal) => console.log('Closed!'))
React Hooks
// Access state
function MyComponent() {
const { visible, params } = UserModal.useState()
return (
<div>
<p>Modal is {visible ? 'open' : 'closed'}</p>
<p>User: {params.username}</p>
</div>
)
}
// Dynamic props
function MyComponent({ theme }) {
UserModal.useProps({
theme: theme,
title: 'User Modal'
}, [theme])
return <button onClick={UserModal.open}>Open</button>
}
Read-Only Properties
// Visibility
console.log(MyModal.isVisible) // boolean
// Current params
console.log(MyModal.currentParams) // Params
// Stack position (z-index)
console.log(MyModal.stackIndex) // number (-1 if not in stack)
// Pending request
console.log(MyModal.hasPendingRequest) // boolean
// Portal ID
console.log(MyModal.id) // string
// Wrapper ref
console.log(MyModal.ref.current) // RefType
Content Props
MyModal.content((props) => {
const {
// State
visible, // boolean
params, // current parameters
// Control
toggle, // () => Promise<void>
close, // () => Promise<void>
open, // (params?) => Promise<void>
setParams, // (next) => void
// Request
request, // { resolve, reject } | null
// Ref
ref, // React.RefObject<RefType>
// Custom parameters
...yourParams // from .open() or .request()
} = props
return <div>Content</div>
})
Portal Types
// Modal - centered overlay
import { modal } from '@codeleap/portals'
const MyModal = modal()
// Drawer - side panel
import { drawer } from '@codeleap/portals'
const MyDrawer = drawer()
// BottomSheet - bottom panel
import { bottomSheet } from '@codeleap/portals'
const MySheet = bottomSheet()
// Alert - utility for typed alerts
import { alert } from '@codeleap/portals'
alert.error({ title: 'Error', body: 'Message' })
alert.warn({ title: 'Warning', body: 'Message' })
alert.info({ title: 'Info', body: 'Message' })
alert.ask({ title: 'Question', body: 'Message' })
alert.custom({ title: 'Custom', customData: {} })
Global Configuration
import { Modal, Drawer, BottomSheet, Alert } from '@codeleap/portals'
// Set wrapper components
Modal.WrapperComponent = MyModalWrapper
Drawer.WrapperComponent = MyDrawerWrapper
BottomSheet.WrapperComponent = MyBottomSheetWrapper
// Set default transition durations
Modal.DEFAULT_TRANSITION_DURATION = 300
Drawer.DEFAULT_TRANSITION_DURATION = 250
BottomSheet.DEFAULT_TRANSITION_DURATION = 200
// Configure bottom sheet ref methods
BottomSheet.openKeyMethod = 'snapToIndex'
BottomSheet.closeKeyMethod = 'close'
// Set alert modal
Alert.modal = modal({ id: 'ALERT' }).content(...)
Global Outlet
import { Portal } from '@codeleap/portals'
function App() {
return (
<div>
<YourAppContent />
<Portal.GlobalOutlet />
</div>
)
}
Portal Registry
import { Portal, Modal } from '@codeleap/portals'
// Access by ID
const portal = Portal.registry.getInstance('USER_MODAL')
const modal = Modal.registry.getInstance('MY_MODAL')
// Get all portals
const all = Portal.registry.getAll()
// Filter portals
const openPortals = Portal.registry.filter(p => p.isVisible)
// Stack operations
Portal.registry.push('MODAL_ID')
Portal.registry.remove('MODAL_ID')
const index = Portal.registry.getStackIndex('MODAL_ID')
// Clear all
Portal.registry.clear()
TypeScript
import { modal } from '@codeleap/portals'
// Define types
interface Params {
userId: string
mode: 'view' | 'edit'
}
interface Result {
saved: boolean
user?: User
}
interface Metadata {
category: string
}
interface RefType {
focus: () => void
}
interface WrapperProps {
title: string
theme: 'light' | 'dark'
}
// Create typed portal
const TypedModal = modal<Params, Result, Metadata, RefType, WrapperProps>()
.content((props) => {
// Fully typed props
const { userId, mode, request } = props
return <div>Content</div>
})
// Type-safe usage
const result = await TypedModal.request({
userId: '123',
mode: 'edit'
})
if (result.saved) {
console.log('User saved')
}
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
id | string | auto | Unique identifier |
initialParams | Params | () => Promise<Params> | {} | Initial parameters |
startsOpen | boolean | () => Promise<boolean> | false | Open on mount |
independent | boolean | false | Don't use global stack |
rendersWhenHidden | boolean | false | Render when not visible |
resetParamsOnClose | boolean | true | Reset params on close |
transitionDuration | number | class default | Animation duration (ms) |
metadata | Metadata | {} | Additional metadata |