mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-08-09 07:25:19 +02:00
feat: preserve scroll and scroll on connect, better responsive mobile settings menu
This commit is contained in:
parent
34b3e4ae20
commit
8f1b685f4e
3 changed files with 88 additions and 1 deletions
44
app/javascript/controllers/preserve_scroll_controller.js
Normal file
44
app/javascript/controllers/preserve_scroll_controller.js
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
import { Controller } from "@hotwired/stimulus"
|
||||||
|
|
||||||
|
/*
|
||||||
|
https://dev.to/konnorrogers/maintain-scroll-position-in-turbo-without-data-turbo-permanent-2b1i
|
||||||
|
modified to add support for horizontal scrolling
|
||||||
|
|
||||||
|
only requirement is that the element has an id
|
||||||
|
*/
|
||||||
|
export default class extends Controller {
|
||||||
|
static scrollPositions = {}
|
||||||
|
|
||||||
|
connect() {
|
||||||
|
this.preserveScrollBound = this.preserveScroll.bind(this)
|
||||||
|
this.restoreScrollBound = this.restoreScroll.bind(this)
|
||||||
|
|
||||||
|
window.addEventListener("turbo:before-cache", this.preserveScrollBound)
|
||||||
|
window.addEventListener("turbo:before-render", this.restoreScrollBound)
|
||||||
|
window.addEventListener("turbo:render", this.restoreScrollBound)
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnect() {
|
||||||
|
window.removeEventListener("turbo:before-cache", this.preserveScrollBound)
|
||||||
|
window.removeEventListener("turbo:before-render", this.restoreScrollBound)
|
||||||
|
window.removeEventListener("turbo:render", this.restoreScrollBound)
|
||||||
|
}
|
||||||
|
|
||||||
|
preserveScroll() {
|
||||||
|
if (!this.element.id) return
|
||||||
|
|
||||||
|
this.constructor.scrollPositions[this.element.id] = {
|
||||||
|
top: this.element.scrollTop,
|
||||||
|
left: this.element.scrollLeft
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
restoreScroll(event) {
|
||||||
|
if (!this.element.id) return
|
||||||
|
|
||||||
|
if (this.constructor.scrollPositions[this.element.id]) {
|
||||||
|
this.element.scrollTop = this.constructor.scrollPositions[this.element.id].top
|
||||||
|
this.element.scrollLeft = this.constructor.scrollPositions[this.element.id].left
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
43
app/javascript/controllers/scroll_on_connect_controller.js
Normal file
43
app/javascript/controllers/scroll_on_connect_controller.js
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
import { Controller } from "@hotwired/stimulus"
|
||||||
|
|
||||||
|
export default class extends Controller {
|
||||||
|
static values = {
|
||||||
|
selector: { type: String, default: "[aria-current=\"page\"]" },
|
||||||
|
delay: { type: Number, default: 500 }
|
||||||
|
}
|
||||||
|
|
||||||
|
connect() {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.scrollToActiveItem()
|
||||||
|
}, this.delayValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollToActiveItem() {
|
||||||
|
const activeItem = this.element?.querySelector(this.selectorValue)
|
||||||
|
|
||||||
|
console.log(activeItem)
|
||||||
|
|
||||||
|
if (!activeItem) return
|
||||||
|
|
||||||
|
const scrollContainer = this.element
|
||||||
|
const containerRect = scrollContainer.getBoundingClientRect()
|
||||||
|
const activeItemRect = activeItem.getBoundingClientRect()
|
||||||
|
|
||||||
|
const scrollPositionX = (activeItemRect.left + scrollContainer.scrollLeft) -
|
||||||
|
(containerRect.width / 2) +
|
||||||
|
(activeItemRect.width / 2)
|
||||||
|
|
||||||
|
const scrollPositionY = (activeItemRect.top + scrollContainer.scrollTop) -
|
||||||
|
(containerRect.height / 2) +
|
||||||
|
(activeItemRect.height / 2)
|
||||||
|
|
||||||
|
console.log(scrollPositionX, scrollPositionY)
|
||||||
|
|
||||||
|
// Smooth scroll to position
|
||||||
|
scrollContainer.scrollTo({
|
||||||
|
top: Math.max(0, scrollPositionY),
|
||||||
|
left: Math.max(0, scrollPositionX),
|
||||||
|
behavior: 'smooth'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -67,7 +67,7 @@ nav_sections = [
|
||||||
<% end %>
|
<% end %>
|
||||||
</section>
|
</section>
|
||||||
</nav>
|
</nav>
|
||||||
<nav class="space-y-4 overflow-y-auto md:hidden" id="mobile-settings-nav">
|
<nav class="space-y-4 overflow-y-auto md:hidden" id="mobile-settings-nav" data-controller="preserve-scroll scroll-on-connect">
|
||||||
<ul class="flex space-y-1">
|
<ul class="flex space-y-1">
|
||||||
<li>
|
<li>
|
||||||
<%= render LinkComponent.new(
|
<%= render LinkComponent.new(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue