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:
@@ -491,9 +491,11 @@ class Rsx {
|
||||
}
|
||||
|
||||
// Collect any extra parameters for query string
|
||||
// Filter out internal parameters that should not appear in URLs
|
||||
const internal_params = ['_loader_title_hint'];
|
||||
const query_params = {};
|
||||
for (const key in params) {
|
||||
if (!used_params[key]) {
|
||||
if (!used_params[key] && !internal_params.includes(key)) {
|
||||
query_params[key] = params[key];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -523,6 +523,37 @@ NAVIGATION
|
||||
Spa.action.reload(); // Reload current action
|
||||
Spa.layout.update_nav(); // Call layout method
|
||||
|
||||
Loader Title Hint:
|
||||
When navigating from a list to a detail page, you can provide a hint
|
||||
for the page title to display while the action loads its data. This
|
||||
provides immediate visual feedback instead of showing a blank or
|
||||
generic title during the loading state.
|
||||
|
||||
Add data-loader-title-hint attribute to links:
|
||||
|
||||
<a href="<%= Rsx.Route('Contacts_View_Action', {id: contact.id}) %>"
|
||||
data-loader-title-hint="<%= contact.name %>">
|
||||
<%= contact.name %>
|
||||
</a>
|
||||
|
||||
When the link is clicked:
|
||||
1. document.title is immediately set to the hint value
|
||||
2. The hint is passed to the action as this.args._loader_title_hint
|
||||
3. Action can use the hint while loading, then replace with real title
|
||||
|
||||
Using the Hint in Actions:
|
||||
async page_title() {
|
||||
// Show hint while loading, real title when data is ready
|
||||
if (this.is_loading() && this.args._loader_title_hint) {
|
||||
return this.args._loader_title_hint;
|
||||
}
|
||||
return `Contact: ${this.data.contact.name}`;
|
||||
}
|
||||
|
||||
The _loader_title_hint parameter is automatically filtered from URLs
|
||||
generated by Rsx.Route(), so it never appears in the browser address
|
||||
bar or generated links.
|
||||
|
||||
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