Add SPA dispatch events and auto-close modals on navigation
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -577,6 +577,10 @@ class Spa {
|
||||
// (Browser refresh scroll is handled separately by Rsx._restore_scroll_on_refresh)
|
||||
Rsx.reset_pending_scroll();
|
||||
|
||||
// Trigger spa_dispatch_start event - allows cleanup before navigation
|
||||
// Use case: close modals, cancel pending operations, etc.
|
||||
Rsx.trigger('spa_dispatch_start', { url });
|
||||
|
||||
try {
|
||||
const opts = {
|
||||
history: options.history || 'auto',
|
||||
@@ -943,10 +947,13 @@ class Spa {
|
||||
// This is the action - set reference but don't wait
|
||||
Spa._action = component;
|
||||
|
||||
// After action is fully ready (on_load + on_ready complete), retry scroll restoration
|
||||
// This handles cases where on_load fetches data that increases page height
|
||||
// After action is fully ready (on_load + on_ready complete)
|
||||
component.ready().then(() => {
|
||||
// Retry scroll restoration - handles cases where on_load fetches data that increases page height
|
||||
Rsx.try_restore_scroll();
|
||||
|
||||
// Trigger spa_dispatch_ready event - action is fully loaded and rendered
|
||||
Rsx.trigger('spa_dispatch_ready', { url, action: component });
|
||||
});
|
||||
} else {
|
||||
// This is a layout
|
||||
|
||||
@@ -692,6 +692,29 @@ Returns: void (does not wait for close)
|
||||
|
||||
Note: Call Modal.close() to dismiss the modal programmatically.
|
||||
|
||||
================================================================================
|
||||
SPA INTEGRATION
|
||||
================================================================================
|
||||
|
||||
The Modal system automatically integrates with SPA navigation:
|
||||
|
||||
Auto-Close on Navigation
|
||||
When SPA navigation begins (spa_dispatch_start event), any open modal
|
||||
is automatically closed. This prevents stale modals from persisting
|
||||
across page transitions.
|
||||
|
||||
This behavior is automatic - no configuration required.
|
||||
|
||||
Modal Flow and Navigation
|
||||
If you need to navigate after a modal action, use Spa.dispatch():
|
||||
|
||||
const result = await Modal.form({...});
|
||||
if (result) {
|
||||
Spa.dispatch(Rsx.Route('Target_Action'));
|
||||
}
|
||||
|
||||
The modal closes first, then navigation proceeds.
|
||||
|
||||
================================================================================
|
||||
MODAL STATE MANAGEMENT
|
||||
================================================================================
|
||||
|
||||
@@ -580,6 +580,60 @@ NAVIGATION
|
||||
generated by Rsx.Route(), so it never appears in the browser address
|
||||
bar or generated links.
|
||||
|
||||
SPA EVENTS
|
||||
The SPA system fires global events that can be used to hook into the
|
||||
navigation lifecycle. Register handlers using Rsx.on():
|
||||
|
||||
spa_dispatch_start
|
||||
Fired at the beginning of navigation, before the old action is destroyed.
|
||||
Use for cleanup before page transition.
|
||||
|
||||
Rsx.on('spa_dispatch_start', (data) => {
|
||||
console.log('Navigating to:', data.url);
|
||||
// Close modals, cancel pending operations, etc.
|
||||
});
|
||||
|
||||
Data payload:
|
||||
url: Target URL being navigated to
|
||||
|
||||
Common uses:
|
||||
- Close open modals (Modal system does this automatically)
|
||||
- Cancel pending Ajax requests
|
||||
- Save unsaved form state
|
||||
- Stop video/audio playback
|
||||
|
||||
spa_dispatch_ready
|
||||
Fired after the new action has fully loaded (on_ready complete).
|
||||
Use for post-navigation setup that needs the action to be ready.
|
||||
|
||||
Rsx.on('spa_dispatch_ready', (data) => {
|
||||
console.log('Action ready:', data.action.constructor.name);
|
||||
// Perform post-navigation actions
|
||||
});
|
||||
|
||||
Data payload:
|
||||
url: Current URL
|
||||
action: The action component instance (fully loaded)
|
||||
|
||||
Common uses:
|
||||
- Analytics page view tracking
|
||||
- Focus management after navigation
|
||||
- Lazy-load additional resources
|
||||
|
||||
Example: Custom navigation tracking
|
||||
|
||||
class Analytics_Tracker {
|
||||
static on_app_modules_init() {
|
||||
Rsx.on('spa_dispatch_start', () => {
|
||||
Analytics.track_page_exit();
|
||||
});
|
||||
|
||||
Rsx.on('spa_dispatch_ready', (data) => {
|
||||
Analytics.track_page_view(data.url);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
SESSION VALIDATION
|
||||
After each SPA navigation (except initial load and back/forward), the client
|
||||
validates its state against the server by calling Rsx.validate_session().
|
||||
|
||||
Reference in New Issue
Block a user