Skip to content

Commit 975ef3b

Browse files
committed
The navbar indicates the current section
1 parent 5bbfe56 commit 975ef3b

1 file changed

Lines changed: 56 additions & 10 deletions

File tree

src/components/AppHeader.vue

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,35 +23,40 @@
2323
<li>
2424
<a
2525
href="#about"
26-
class="font-medium text-gray-700 dark:text-gray-300 hover:text-blue-600 dark:hover:text-blue-400 transition-colors"
26+
:class="isActive('about') ? 'text-blue-600 dark:text-blue-400' : 'text-gray-700 dark:text-gray-300'"
27+
class="font-medium hover:text-blue-600 dark:hover:text-blue-400 transition-colors"
2728
>About</a
2829
>
2930
</li>
3031
<li>
3132
<a
3233
href="#publications"
33-
class="font-medium text-gray-700 dark:text-gray-300 hover:text-blue-600 dark:hover:text-blue-400 transition-colors"
34+
:class="isActive('publications') ? 'text-blue-600 dark:text-blue-400' : 'text-gray-700 dark:text-gray-300'"
35+
class="font-medium hover:text-blue-600 dark:hover:text-blue-400 transition-colors"
3436
>Publications</a
3537
>
3638
</li>
3739
<li>
3840
<a
3941
href="#evolution"
40-
class="font-medium text-gray-700 dark:text-gray-300 hover:text-blue-600 dark:hover:text-blue-400 transition-colors"
42+
:class="isActive('evolution') ? 'text-blue-600 dark:text-blue-400' : 'text-gray-700 dark:text-gray-300'"
43+
class="font-medium hover:text-blue-600 dark:hover:text-blue-400 transition-colors"
4144
>Evolution</a
4245
>
4346
</li>
4447
<li>
4548
<a
4649
href="#authors"
47-
class="font-medium text-gray-700 dark:text-gray-300 hover:text-blue-600 dark:hover:text-blue-400 transition-colors"
50+
:class="isActive('authors') ? 'text-blue-600 dark:text-blue-400' : 'text-gray-700 dark:text-gray-300'"
51+
class="font-medium hover:text-blue-600 dark:hover:text-blue-400 transition-colors"
4852
>Authors</a
4953
>
5054
</li>
5155
<li>
5256
<a
5357
href="#contributors"
54-
class="font-medium text-gray-700 dark:text-gray-300 hover:text-blue-600 dark:hover:text-blue-400 transition-colors"
58+
:class="isActive('contributors') ? 'text-blue-600 dark:text-blue-400' : 'text-gray-700 dark:text-gray-300'"
59+
class="font-medium hover:text-blue-600 dark:hover:text-blue-400 transition-colors"
5560
>Contributors</a
5661
>
5762
</li>
@@ -146,31 +151,36 @@
146151
<a
147152
href="#about"
148153
@click="closeMobileMenu"
149-
class="block px-3 py-2 text-base font-medium text-gray-700 dark:text-gray-300 hover:text-blue-600 dark:hover:text-blue-400 hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
154+
:class="isActive('about') ? 'text-blue-600 dark:text-blue-400 bg-blue-50 dark:bg-gray-800' : 'text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-800'"
155+
class="block px-3 py-2 text-base font-medium hover:text-blue-600 dark:hover:text-blue-400 rounded-md"
150156
>About</a
151157
>
152158
<a
153159
href="#publications"
154160
@click="closeMobileMenu"
155-
class="block px-3 py-2 text-base font-medium text-gray-700 dark:text-gray-300 hover:text-blue-600 dark:hover:text-blue-400 hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
161+
:class="isActive('publications') ? 'text-blue-600 dark:text-blue-400 bg-blue-50 dark:bg-gray-800' : 'text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-800'"
162+
class="block px-3 py-2 text-base font-medium hover:text-blue-600 dark:hover:text-blue-400 rounded-md"
156163
>Publications</a
157164
>
158165
<a
159166
href="#evolution"
160167
@click="closeMobileMenu"
161-
class="block px-3 py-2 text-base font-medium text-gray-700 dark:text-gray-300 hover:text-blue-600 dark:hover:text-blue-400 hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
168+
:class="isActive('evolution') ? 'text-blue-600 dark:text-blue-400 bg-blue-50 dark:bg-gray-800' : 'text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-800'"
169+
class="block px-3 py-2 text-base font-medium hover:text-blue-600 dark:hover:text-blue-400 rounded-md"
162170
>Evolution</a
163171
>
164172
<a
165173
href="#authors"
166174
@click="closeMobileMenu"
167-
class="block px-3 py-2 text-base font-medium text-gray-700 dark:text-gray-300 hover:text-blue-600 dark:hover:text-blue-400 hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
175+
:class="isActive('authors') ? 'text-blue-600 dark:text-blue-400 bg-blue-50 dark:bg-gray-800' : 'text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-800'"
176+
class="block px-3 py-2 text-base font-medium hover:text-blue-600 dark:hover:text-blue-400 rounded-md"
168177
>Authors</a
169178
>
170179
<a
171180
href="#contributors"
172181
@click="closeMobileMenu"
173-
class="block px-3 py-2 text-base font-medium text-gray-700 dark:text-gray-300 hover:text-blue-600 dark:hover:text-blue-400 hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
182+
:class="isActive('contributors') ? 'text-blue-600 dark:text-blue-400 bg-blue-50 dark:bg-gray-800' : 'text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-800'"
183+
class="block px-3 py-2 text-base font-medium hover:text-blue-600 dark:hover:text-blue-400 rounded-md"
174184
>Contributors</a
175185
>
176186
<button
@@ -233,13 +243,23 @@ export default {
233243
data() {
234244
return {
235245
isMobileMenuOpen: false,
246+
activeSection: '',
247+
observer: null,
236248
}
237249
},
238250
mounted() {
239251
// Init smooth scroll
240252
this.initSmoothScroll()
253+
// Init scroll Spy
254+
this.initScrollSpy()
255+
},
256+
beforeUnmount() {
257+
if (this.observer) this.observer.disconnect();
241258
},
242259
methods: {
260+
isActive(section) {
261+
return this.activeSection === section;
262+
},
243263
toggleDarkMode() {
244264
this.$emit("toggle-dark-mode")
245265
},
@@ -249,14 +269,40 @@ export default {
249269
closeMobileMenu() {
250270
this.isMobileMenuOpen = false
251271
},
272+
initScrollSpy() {
273+
const sections = document.querySelectorAll('section');
274+
275+
const options = {
276+
root: null,
277+
rootMargin: '-45% 0px -45% 0px',
278+
threshold: 0
279+
};
280+
281+
this.observer = new IntersectionObserver((entries) => {
282+
entries.forEach((entry) => {
283+
if (entry.isIntersecting) {
284+
this.activeSection = entry.target.id;
285+
}
286+
});
287+
}, options);
288+
289+
sections.forEach((section) => {
290+
this.observer.observe(section);
291+
});
292+
},
252293
initSmoothScroll() {
294+
const self = this;
295+
253296
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
254297
anchor.addEventListener("click", function (e) {
255298
const href = this.getAttribute("href")
256299
if (href !== "#" && href.length > 1) {
257300
e.preventDefault()
258301
const target = document.querySelector(href)
259302
if (target) {
303+
self.activeSection = href.substring(1);
304+
self.closeMobileMenu();
305+
260306
const headerOffset = 64
261307
const elementPosition = target.getBoundingClientRect().top
262308
const offsetPosition =

0 commit comments

Comments
 (0)