mirror of
https://github.com/we-promise/sure.git
synced 2026-07-12 12:55:20 +00:00
fix(settings): preserve content scroll position per page across navigation (#2277)
Settings nav items are plain Turbo Drive links (full-body visits); Turbo only restores window scroll, so the nested overflow-y-auto content container snapped to the top on every settings navigation. Add a settings-scroll Stimulus controller that saves/restores the content scroll keyed by pathname: returning to a page restores its scroll, a new page opens at the top, and a same-page re-render (settings form auto-submit) keeps scroll. Distinct from the nav's preserve-scroll controller, which keys by element id to intentionally carry one position across pages. Verified live: scroll 250 on Preferences -> Appearance opens at top -> back to Preferences restores 250.
This commit is contained in:
committed by
GitHub
parent
74d0452a2b
commit
5f391f7fff
39
app/javascript/controllers/settings_scroll_controller.js
Normal file
39
app/javascript/controllers/settings_scroll_controller.js
Normal file
@@ -0,0 +1,39 @@
|
||||
import { Controller } from "@hotwired/stimulus";
|
||||
|
||||
// Preserves the settings content scroll position PER PAGE across Turbo Drive
|
||||
// navigation. Settings nav items are plain links (full-body Turbo visits), and
|
||||
// Turbo only restores window scroll — so this nested overflow-y-auto container
|
||||
// snaps to top on every visit.
|
||||
//
|
||||
// Keyed by pathname: returning to a page restores its scroll, a brand-new page
|
||||
// starts at the top, and a same-page re-render (e.g. a settings form that
|
||||
// auto-submits) keeps scroll. This differs from the nav's `preserve-scroll`
|
||||
// controller, which intentionally carries one position across all pages because
|
||||
// the nav is the same persistent element on every settings page.
|
||||
export default class extends Controller {
|
||||
static positions = {};
|
||||
|
||||
connect() {
|
||||
this.save = this.save.bind(this);
|
||||
document.addEventListener("turbo:before-cache", this.save);
|
||||
this.restore();
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
document.removeEventListener("turbo:before-cache", this.save);
|
||||
}
|
||||
|
||||
save() {
|
||||
this.constructor.positions[window.location.pathname] = {
|
||||
top: this.element.scrollTop,
|
||||
left: this.element.scrollLeft,
|
||||
};
|
||||
}
|
||||
|
||||
restore() {
|
||||
const pos = this.constructor.positions[window.location.pathname];
|
||||
if (!pos) return;
|
||||
this.element.scrollTop = pos.top;
|
||||
this.element.scrollLeft = pos.left;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user