Modal Navigation
Stack-based navigation inside modals with automatic back buttons, smooth animations, and declarative wiring via rel attributes.
Build multi-step workflows without z-index nightmares. One modal shell, multiple screens, proper navigation.
Basic usage
Simple navigation
import { Modal, ModalNavigation } from '@appitude/bravo';
// Create a navigation instance
const nav = new ModalNavigation();
// Create a modal
const welcome = new Modal({
title: 'Welcome',
content: '<p>Hello from modal navigation!</p>'
});
// Push the modal to navigation and show
nav.push(welcome);
nav.show();
Using existing modals
// If you already have a modal in the DOM
const existingModal = new Modal('#my-existing-modal');
const nav = new ModalNavigation();
nav.push(existingModal);
nav.show();
Building a navigation flow
const nav = new ModalNavigation();
// First screen with a button to navigate forward
const first = new Modal({
title: 'Step 1',
content: `
<p>This is the first screen.</p>
<button rel="step-2" class="btn btn-primary">Continue</button>
`
});
// Second screen with ID that matches the rel attribute
const second = new Modal({
id: 'step-2',
title: 'Step 2',
content: `
<p>You made it to step 2!</p>
<button rel="back" class="btn btn-secondary">Go Back</button>
<button rel="close" class="btn btn-success">Done</button>
`
});
// Start the navigation
nav.push(first);
nav.show();
Advanced navigation
Push/pop navigation
const nav = new ModalNavigation();
nav.push(firstModal); // Add to stack and navigate forward
nav.show(); // Open the navigation
nav.push(secondModal); // Navigate to next screen
nav.pop(); // Go back one screen
nav.close(); // Close entire navigation
Using rel
attributes
Any element with a rel
attribute becomes a navigation trigger:
<button rel="settings">Settings</button> <!-- Navigate to #settings modal -->
<button rel="back">โ Back</button> <!-- Go to previous screen -->
<button rel="close">Cancel</button> <!-- Close entire navigation -->
When clicked, the navigation:
- First checks if a modal with that ID was already pushed (reuses from cache)
- Otherwise looks for an existing Modal instance with that ID
- If neither found, looks for an existing modal element in the DOM and creates a Modal instance from it
- Pushes the modal onto the navigation stack
Controlling the back button
The back button automatically appears when stack depth > 1. You can disable it for specific modals:
const finalStep = new Modal({
title: 'Complete',
backButton: { disabled: true }, // No going back from here
content: '<p>This is the final screen.</p>'
});
See the shopping demo above where the order confirmation prevents going back after purchase.
Transition animations
Choose between two animation styles when navigating between screens:
// Slide animation (default) - iOS-style horizontal slide
const slideNav = new ModalNavigation({
animation: 'slide'
});
// Morph animation - Smooth size morphing between screens
const morphNav = new ModalNavigation({
animation: 'morph'
});
The slide animation provides iOS-style navigation with horizontal movement. The morph animation smoothly resizes the modal between different content sizes.
Configuration & Events
Configuration
new ModalNavigation({
animation: 'slide', // Animation type: 'slide' or 'morph'
backButton: {
disabled: false, // Show/hide back button
text: '' // Custom back button text/icon
},
closeButton: {
disabled: false, // Show/hide close button
text: '' // Custom close button text/icon
}
});
Events
// Navigation lifecycle
document.addEventListener('open.bs.nav', handler); // Navigation opening
document.addEventListener('opened.bs.nav', handler); // Navigation opened
document.addEventListener('close.bs.nav', handler); // Navigation closing
// Navigation movement
document.addEventListener('forward.bs.nav', handler); // Starting forward navigation
document.addEventListener('forwarding.bs.nav', handler); // Animation in progress
document.addEventListener('forwarded.bs.nav', handler); // Forward complete
document.addEventListener('back.bs.nav', handler); // Starting back navigation
document.addEventListener('backing.bs.nav', handler); // Animation in progress
document.addEventListener('backed.bs.nav', handler); // Back complete
All events include e.detail.stack
with the current navigation stack.
Key features
- Navigation stack โ Push/pop screens instead of stacking multiple modals
- Automatic back button โ Appears when needed (stack > 1), no manual wiring
- Smooth transitions โ Slide or morph animations between screens
- Declarative navigation โ Use
rel
attributes to wire up navigation - Modal reuse โ Previously shown modals are cached and reused
- Single backdrop โ No z-index issues or backdrop flashing
- CSS hooks โ
.modal-navigation
and.modal-navigation-stacked
classes for custom styling