PageSourceSearch

https://static.vitamese.com/assets/controllers/admin_sidebar_controller-5fe41581.js

js vitamese.com collected 2026-10-02 16:05:19 UTC 3,835 bytes, 119 lines download raw bytes

1import { Controller } from "@hotwired/stimulus"
2
3export default class extends Controller {
4  static targets = ["sidebar", "overlay"]
5
6  connect() {
7    // Initialize sidebar state based on screen size
8    this.initializeSidebar()
9    window.addEventListener("resize", this.handleResize.bind(this))
10    this.setupNavigationLinks()
11    this.setupTurboEvents()
12
13    this.boundUpdateActiveLink = this.updateActiveLink.bind(this)
14    document.addEventListener("turbo:frame-load", this.boundUpdateActiveLink)
15  }
16
17  disconnect() {
18    window.removeEventListener("resize", this.handleResize.bind(this))
19    document.removeEventListener("turbo:frame-load", this.boundUpdateActiveLink)
20  }
21
22  updateActiveLink(event) {
23    const url = new URL(window.location.href)
24    const currentPath = url.pathname
25    const currentParams = url.searchParams
26
27    const navLinks = this.sidebarTarget.querySelectorAll('nav a[href]')
28    navLinks.forEach(link => {
29      link.classList.remove("active");
30      const linkUrl = new URL(link.href)
31      const linkPath = linkUrl.pathname
32      const linkParams = linkUrl.searchParams
33
34      // Check if this is a snippet section link
35      if (linkPath.includes('/admin/snippets') && linkParams.has('section')) {
36        // For snippet sections, mark as active if the section matches, regardless of subsection
37        const isActive = linkPath === currentPath &&
38                        linkParams.get('section') === currentParams.get('section')
39        link.classList.toggle("active", isActive)
40      } else {
41        // For other links, use exact matching
42        const linkFullPath = linkUrl.pathname + linkUrl.search
43        const currentFullPath = url.pathname + url.search
44        link.classList.toggle("active", linkFullPath === currentFullPath)
45      }
46    })
47  }
48
49  initializeSidebar() {
50    if (window.innerWidth < 768) {
51      // Mobile: hide sidebar by default
52      this.sidebarTarget.classList.add("-translate-x-full")
53      this.overlayTarget.style.display = "none"
54    } else {
55      // Desktop: show sidebar by default
56      this.sidebarTarget.classList.remove("-translate-x-full")
57      this.overlayTarget.style.display = "none"
58    }
59  }
60
61  toggleSidebar() {
62    if (this.isSidebarOpen()) {
63      this.closeSidebar()
64    } else {
65      this.openSidebar()
66    }
67  }
68
69  openSidebar() {
70    this.sidebarTarget.classList.remove("-translate-x-full")
71    this.overlayTarget.style.display = "block"
72    document.body.style.overflow = "hidden"
73  }
74
75  closeSidebar() {
76    this.sidebarTarget.classList.add("-translate-x-full")
77    this.overlayTarget.style.display = "none"
78    document.body.style.overflow = "auto"
79  }
80
81  handleResize() {
82    if (window.innerWidth >= 768) {
83      // Desktop: show sidebar, hide overlay
84      this.sidebarTarget.classList.remove("-translate-x-full")
85      this.overlayTarget.style.display = "none"
86      document.body.style.overflow = "auto"
87    } else {
88      // Mobile: hide sidebar by default
89      this.sidebarTarget.classList.add("-translate-x-full")
90      this.overlayTarget.style.display = "none"
91      document.body.style.overflow = "auto"
92    }
93  }
94
95  isSidebarOpen() {
96    return !this.sidebarTarget.classList.contains("-translate-x-full")
97  }
98
99  setupNavigationLinks() {
100    // Find all navigation links in the sidebar
101    const navLinks = this.sidebarTarget.querySelectorAll('nav a[href]')
102
103    navLinks.forEach(link => {
104      link.addEventListener('click', (event) => {
105        // Only add delay on mobile when sidebar is open
106        if (window.innerWidth < 768 && this.isSidebarOpen()) {
107          // Add a brief delay before closing sidebar
108          setTimeout(() => {
109            this.closeSidebar()
110          }, 200)
111        }
112      })
113    })
114  }
115
116  setupTurboEvents() {
117    // No longer needed since sidebar persists with data-turbo-permanent
118  }
119}

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.