diff --git a/_includes/navbar.html b/_includes/navbar.html
index 2323b3f..b39ec0c 100644
--- a/_includes/navbar.html
+++ b/_includes/navbar.html
@@ -3,7 +3,7 @@
{% include_cached logo.svg %}
-
+
{%- for item in site.i18n.menu.items -%}
{% comment %}
Algunos items del menú tienen layouts para indicar que
@@ -22,7 +22,7 @@
{%- assign href = post.url | default: item.href -%}
{%- assign active = include.active_cache_key | equals: href -%}
-
-
+
{{ item.title }}
{%- if active -%}
diff --git a/_layouts/default.html b/_layouts/default.html
index 09343ce..9766097 100644
--- a/_layouts/default.html
+++ b/_layouts/default.html
@@ -34,7 +34,7 @@
{%- assign active_cache_key = page.url | menu_active_item | default: 'none' -%}
{%- include_cached navbar.html active_cache_key=active_cache_key %}
-
+
{{ content }}
diff --git a/_packs/controllers/menu_controller.js b/_packs/controllers/menu_controller.js
new file mode 100644
index 0000000..7a79a3b
--- /dev/null
+++ b/_packs/controllers/menu_controller.js
@@ -0,0 +1,32 @@
+import 'core-js/stable'
+import 'regenerator-runtime/runtime'
+import { Controller } from 'stimulus'
+
+export default class extends Controller {
+ static targets = [ 'item' ]
+
+ connect () {
+ window.addEventListener('scroll:section', event => this.update(event.detail.id))
+ }
+
+ get items () {
+ if (!this._items) {
+ this._items = {}
+
+ for (const item of this.itemTargets) {
+ this._items[item.href.split('#')[1]] = item
+ }
+ }
+
+ return this._items
+ }
+
+ update (id) {
+ console.log(id)
+ for (const item of Object.values(this.items)) {
+ item.classList.remove('active')
+ }
+
+ if (this.items[id]) this.items[id].classList.add('active')
+ }
+}
diff --git a/_packs/controllers/scroll_controller.js b/_packs/controllers/scroll_controller.js
new file mode 100644
index 0000000..5b168a5
--- /dev/null
+++ b/_packs/controllers/scroll_controller.js
@@ -0,0 +1,43 @@
+import 'core-js/stable'
+import 'regenerator-runtime/runtime'
+import { Controller } from 'stimulus'
+
+/*
+ * Al navegar por el sitio y llegar a ciertas secciones, se van
+ * activando ítems del menú.
+ *
+ * Para eso configuramos un IntersectionObserver en todo el documento y
+ * a medida que van apareciendo secciones actualizamos el menú.
+ */
+export default class extends Controller {
+ static targets = [ 'section' ]
+
+ connect () {
+ for (const section of this.sectionTargets) {
+ this.observer.observe(section)
+ }
+ }
+
+ /*
+ * Solo nos interesa la primera
+ */
+ get observer () {
+ if (!this._observer) this._observer = new IntersectionObserver((entries, observer) => this.update(entries), this.options)
+
+ return this._observer
+ }
+
+ get options () {
+ if (!this._options) this._options = { threshold: 0, rootMargin: '0px' }
+
+ return this._options
+ }
+
+ update (entries) {
+ const section = entries.find(x => x.isIntersecting)
+
+ if (!section) return
+
+ window.dispatchEvent(new CustomEvent('scroll:section', { detail: { id: section.target.id }}))
+ }
+}