react-native-sequential-modal-manager
v1.0.0
Published
A powerful and flexible npm package that ensures only one modal is open at a time in React Native applications, with support for modal queuing, priority management, and automatic sequencing.
Downloads
4
Maintainers
Readme
React Native Sequential Modal Manager
A powerful and flexible npm package that ensures only one modal is open at a time in React Native applications, with support for modal queuing, priority management, and automatic sequencing.
Features
- 🚀 Sequential Modal Management: Ensure only one modal is visible at any time
- 📋 Priority-based Queueing: Configurable priority levels (LOW, MEDIUM, HIGH, URGENT)
- 🔄 Automatic Sequencing: Modals are shown automatically in priority order
- 🎯 Interruption Control: Control which modals can interrupt others
- 🎨 Flexible API: Simple hook-based API with full TypeScript support
- 🔧 Lifecycle Management: Complete modal lifecycle with callbacks
- 🛡️ Error Handling: Built-in error handling and recovery
- 📱 React Native Optimized: Designed specifically for React Native
Installation
npm install react-native-sequential-modal-manager
# or
yarn add react-native-sequential-modal-managerQuick Start
1. Wrap your app with the provider
import { ModalManagerProvider, SequentialModalContainer } from 'react-native-sequential-modal-manager';
const App = () => (
<ModalManagerProvider>
<SequentialModalContainer>
<YourApp />
</SequentialModalContainer>
</ModalManagerProvider>
);2. Use the hook to show modals
import { useSequentialModal, ModalPriority } from 'react-native-sequential-modal-manager';
const MyComponent = () => {
const { showModal, hideModal } = useSequentialModal();
const handleShowModal = () => {
showModal({
id: 'my-modal',
component: MyModalComponent,
props: { title: 'Hello World' },
priority: ModalPriority.MEDIUM,
});
};
return <Button onPress={handleShowModal} />;
};API Reference
Components
ModalManagerProvider
The main provider component that manages modal state.
<ModalManagerProvider settings={customSettings}>
{children}
</ModalManagerProvider>Props:
settings(optional): Custom settings for the modal managerchildren: React components
SequentialModalContainer
The container component that renders the current modal.
<SequentialModalContainer>
{children}
</SequentialModalContainer>Hooks
useSequentialModal()
The main hook for managing modals.
const {
showModal,
hideModal,
clearQueue,
currentModal,
queue,
queueLength,
hasModal,
} = useSequentialModal();Returns:
showModal(config): Function to show a modalhideModal(id): Function to hide a modalclearQueue(): Function to clear all queued modalscurrentModal: Current visible modal instancequeue: Array of queued modalsqueueLength: Number of modals in queuehasModal(id): Function to check if a modal exists
useModalInstance(id)
Hook to access specific modal instance data.
const {
modal,
isVisible,
isQueued,
hasError,
error,
hideModal,
} = useModalInstance('modal-id');useModalQueue()
Hook to access queue information.
const {
queue,
queueLength,
currentModal,
nextModal,
highPriorityModals,
mediumPriorityModals,
lowPriorityModals,
clearQueue,
removeFromQueue,
hasModal,
} = useModalQueue();Types
ModalConfig
Configuration object for showing a modal.
interface ModalConfig {
id: string; // Unique modal identifier
component: React.ComponentType<any>; // Modal component to render
props?: Record<string, any>; // Props to pass to modal component
priority?: ModalPriority; // Modal priority level
canBeInterrupted?: boolean; // Whether modal can be interrupted
onShow?: () => void; // Called when modal is shown
onHide?: () => void; // Called when modal is hidden
onComplete?: () => void; // Called when modal is completed
onError?: (error: Error) => void; // Called when modal encounters error
backdropDismissible?: boolean; // Whether backdrop can dismiss modal
animationDuration?: number; // Animation duration in ms
}ModalPriority
Enum for modal priority levels.
enum ModalPriority {
LOW = 0, // Lowest priority
MEDIUM = 1, // Default priority
HIGH = 2, // High priority
URGENT = 3, // Highest priority (can interrupt non-interruptible modals)
}Constants
DEFAULT_SETTINGS
Default settings for the modal manager.
const DEFAULT_SETTINGS = {
maxQueueSize: 50, // Maximum number of modals in queue
defaultAnimationDuration: 300, // Default animation duration
enableLogging: __DEV__, // Enable logging in development
enableAnalytics: false, // Enable analytics
};Usage Examples
Basic Modal
const MyComponent = () => {
const { showModal } = useSequentialModal();
const handleShowModal = () => {
showModal({
id: 'basic-modal',
component: BasicModal,
props: { title: 'Basic Modal' },
});
};
return <Button onPress={handleShowModal} />;
};High Priority Modal
const handleShowUrgentModal = () => {
showModal({
id: 'urgent-notification',
component: UrgentNotificationModal,
priority: ModalPriority.HIGH,
canBeInterrupted: false,
onComplete: () => {
console.log('Urgent modal completed');
},
});
};Modal with Custom Props
const handleShowCustomModal = () => {
showModal({
id: 'custom-modal',
component: CustomModal,
props: {
title: 'Custom Modal',
data: { key: 'value' },
onAction: () => console.log('Action performed'),
},
priority: ModalPriority.MEDIUM,
backdropDismissible: false,
animationDuration: 500,
});
};Modal with Lifecycle Callbacks
const handleShowModalWithCallbacks = () => {
showModal({
id: 'callback-modal',
component: CallbackModal,
onShow: () => {
console.log('Modal is now visible');
// Track analytics
},
onHide: () => {
console.log('Modal is now hidden');
// Clean up resources
},
onComplete: () => {
console.log('Modal completed successfully');
// Handle completion
},
onError: (error) => {
console.error('Modal encountered error:', error);
// Handle error
},
});
};Checking Modal Status
const MyComponent = () => {
const { currentModal, queueLength, hasModal } = useSequentialModal();
return (
<View>
<Text>Current Modal: {currentModal?.id || 'None'}</Text>
<Text>Queue Length: {queueLength}</Text>
<Text>Has Login Modal: {hasModal('login-modal') ? 'Yes' : 'No'}</Text>
</View>
);
};Using Modal Instance Hook
const ModalStatusComponent = () => {
const { modal, isVisible, isQueued, hasError, error } = useModalInstance('my-modal');
if (!modal) return <Text>Modal not found</Text>;
return (
<View>
<Text>Status: {modal.status}</Text>
<Text>Visible: {isVisible ? 'Yes' : 'No'}</Text>
<Text>Queued: {isQueued ? 'Yes' : 'No'}</Text>
{hasError && <Text>Error: {error?.message}</Text>}
</View>
);
};Advanced Features
Priority Management
Modals with higher priority will be shown before lower priority modals. URGENT priority modals can interrupt non-interruptible modals.
// This modal will interrupt the current modal
showModal({
id: 'urgent-modal',
component: UrgentModal,
priority: ModalPriority.URGENT,
});
// This modal cannot be interrupted
showModal({
id: 'non-interruptible-modal',
component: NonInterruptibleModal,
priority: ModalPriority.HIGH,
canBeInterrupted: false,
});Queue Management
const { clearQueue, removeFromQueue } = useModalQueue();
// Clear all queued modals
clearQueue();
// Remove specific modal from queue
removeFromQueue('modal-id');Custom Settings
<ModalManagerProvider
settings={{
maxQueueSize: 100,
defaultAnimationDuration: 500,
enableLogging: true,
enableAnalytics: true,
}}
>
{children}
</ModalManagerProvider>Migration from Existing Modal Systems
From React Native Modal
// Before
const [isVisible, setIsVisible] = useState(false);
// After
const { showModal, hideModal } = useSequentialModal();
const handleShowModal = () => {
showModal({
id: 'my-modal',
component: MyModal,
props: { /* your props */ },
});
};From Custom Modal Manager
// Before
modalManager.show('modal-id', ModalComponent, props);
// After
showModal({
id: 'modal-id',
component: ModalComponent,
props: props,
});Performance Considerations
- The package is optimized for React Native performance
- Modals are rendered only when needed
- Queue operations are efficient with O(log n) priority insertion
- Memory is managed automatically with proper cleanup
Error Handling
The package includes comprehensive error handling:
showModal({
id: 'error-handling-modal',
component: ErrorModal,
onError: (error) => {
console.error('Modal error:', error);
// Handle error appropriately
},
});Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
License
MIT License - see LICENSE file for details.
Support
For support, please open an issue on GitHub or contact the maintainers.
