import { Controller } from '@hotwired/stimulus' // Turbo doesn't scroll for navigations, so after the frame swaps // its contents (a sort, filter, or pagination link) this brings the top of the // frame back into view — otherwise clicking pagination at the bottom of the // list leaves you stranded down there. The frame's own scroll-margin-top keeps // it clear of the sticky header. // // `turbo:frame-render` fires only on a content swap, not on the initial page // render, and the frame element itself persists across swaps — so the listener // is bound once in connect(). export default class extends Controller { connect() { this.element.addEventListener('turbo:frame-render', this.#toTop) } disconnect() { this.element.removeEventListener('turbo:frame-render', this.#toTop) } #toTop = () => { this.element.scrollIntoView({ block: 'start', behavior: 'smooth' }) } }