PageSourceSearch

https://survivalinternational.org/assets/controllers/admin/navbar_controller-bcd258c5.js

js survivalinternational.org collected 2026-09-24 08:43:03 UTC 2,105 bytes, 75 lines download raw bytes

1// Hides the navbar when scrolling down and reveals it when scrolling up,
2// with thresholds to prevent triggering on small or accidental scroll movements.
3import { Controller } from "@hotwired/stimulus"
4
5export default class extends Controller {
6  static values = {
7    hideAfter: { type: Number, default: 80 },
8    showAfter: { type: Number, default: 40 }
9  }
10
11  connect() {
12    this.lastY = window.scrollY;
13    this.accumulated = 0;
14    this.scrollHandler = this.#onScroll.bind(this);
15    this.clickHandler = this.#onDocumentClick.bind(this);
16    window.addEventListener('scroll', this.scrollHandler, { passive: true });
17    document.addEventListener('click', this.clickHandler);
18  }
19
20  disconnect() {
21    window.removeEventListener('scroll', this.scrollHandler);
22    document.removeEventListener('click', this.clickHandler);
23  }
24
25  #onScroll() {
26    const y = window.scrollY;
27    const delta = y - this.lastY;
28
29    if (delta === 0) return;
30
31    // Reset accumulator when scroll direction reverses
32    if (this.accumulated !== 0 && (delta > 0) !== (this.accumulated > 0)) {
33      this.accumulated = 0;
34    }
35    this.accumulated += delta;
36
37    if (this.accumulated >= this.hideAfterValue) {
38      this.element.classList.add('navbar--hidden');
39      this.accumulated = 0;
40    } else if (this.accumulated <= -this.showAfterValue) {
41      this.element.classList.remove('navbar--hidden');
42      this.accumulated = 0;
43    }
44
45    // Always reveal at top of page
46    if (y <= 0) {
47      this.element.classList.remove('navbar--hidden');
48      this.accumulated = 0;
49    }
50
51    this.lastY = Math.max(0, y);
52  }
53
54  #onDocumentClick(event) {
55    if (!this.element.contains(event.target)) {
56      this.#closeAllDetails();
57      return;
58    }
59
60    if (event.target.closest('summary')) {
61      this.#closeAllDetails(event.target.closest('details'));
62      return;
63    }
64
65    if (event.target.closest('a')) {
66      this.#closeAllDetails();
67    }
68  }
69
70  #closeAllDetails(except = null) {
71    this.element.querySelectorAll('details[open]').forEach(d => {
72      if (d !== except) d.removeAttribute('open');
73    });
74  }
75}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.