Add loader title hint for SPA navigation feedback

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2025-12-26 22:29:45 +00:00
parent b54484c7ed
commit f08d3de0c8
3 changed files with 57 additions and 4 deletions

View File

@@ -465,7 +465,19 @@ class Spa {
console_debug('Spa', 'Intercepting link click: ' + href);
e.preventDefault();
Spa.dispatch(href, { history: 'auto' });
// Check for loader title hint - provides immediate title feedback while page loads
const loader_title_hint = link.getAttribute('data-loader-title-hint');
const dispatch_options = { history: 'auto' };
if (loader_title_hint) {
// Set document title immediately for instant feedback
document.title = loader_title_hint;
dispatch_options.loader_title_hint = loader_title_hint;
console_debug('Spa', 'Loader title hint: ' + loader_title_hint);
}
Spa.dispatch(href, dispatch_options);
} else {
console_debug('Spa', 'No SPA route match, letting server handle: ' + href);
}
@@ -514,6 +526,7 @@ class Spa {
history: options.history || 'auto',
scroll: 'scroll' in options ? options.scroll : undefined,
triggers: options.triggers !== false,
loader_title_hint: options.loader_title_hint || null,
};
console_debug('Spa', 'Dispatching to: ' + url + ' (history: ' + opts.history + ')');
@@ -660,18 +673,25 @@ class Spa {
const action_class = route_match.action_class;
const action_name = action_class.name;
// Merge loader title hint into action args if provided
// This allows the action to show a placeholder title while loading
let action_args = route_match.args;
if (opts.loader_title_hint) {
action_args = { ...route_match.args, _loader_title_hint: opts.loader_title_hint };
}
// Log successful SPA navigation
console.warn('[Spa.dispatch] Executing SPA navigation', {
url: url,
path: parsed.path,
params: route_match.args,
params: action_args,
action: action_name,
layouts: target_layouts,
history_mode: opts.history
});
// Resolve layout chain - find divergence point and reuse matching layouts
await Spa._resolve_layout_chain(target_layouts, action_name, route_match.args, url);
await Spa._resolve_layout_chain(target_layouts, action_name, action_args, url);
// Scroll Restoration #1: Immediate (after action starts)
// This occurs synchronously after the action component is created