diff --git a/_packs/controllers/menu_controller.js b/_packs/controllers/menu_controller.js index e1b493f..3fe8794 100644 --- a/_packs/controllers/menu_controller.js +++ b/_packs/controllers/menu_controller.js @@ -1,5 +1,3 @@ -import 'core-js/stable' -import 'regenerator-runtime/runtime' import { Controller } from 'stimulus' export default class extends Controller { diff --git a/_packs/controllers/notification_controller.js b/_packs/controllers/notification_controller.js new file mode 100644 index 0000000..17eaaa7 --- /dev/null +++ b/_packs/controllers/notification_controller.js @@ -0,0 +1,80 @@ +import { Controller } from 'stimulus' +import { Liquid } from 'liquidjs' + +/* + * Waits for notifications and shows them by fetching and rendering + * a template. + */ +export default class extends Controller { + connect () { + window.addEventListener('notification', async event => await this.render(event.detail.template, event.detail.data)) + } + + /* + * Renders and replaces notification contents and then shows it. Does + * nothing if the template isn't found. + */ + async render (name, data = {}) { + const response = await fetch(this.template(name)) + + if (!response.ok) return + + data.site = await this.site() + + const template = await response.text() + const html = await this.engine.parseAndRender(template, data) + + this.element.innerHTML = html + this.show() + } + + /* + * Gets the template path from a name + * + * @return [String] + */ + template (name) { + return this.data.get('templates') + name + '.html' + } + + /* + * Shows the notification + */ + show () { + this.element.classList.add('show') + this.element.classList.remove('hide') + } + + /* + * Hides the notification + */ + hide () { + this.element.classList.add('hide') + this.element.classList.remove('show') + } + + /* + * Liquid renderer + * + * @return Liquid + */ + get engine () { + if (!window.liquid) window.liquid = new Liquid() + + return window.liquid + } + + /* + * Site config (actually just translation strings) + * + * @return [Object] + */ + async site () { + if (!window.site) { + const data = await fetch('assets/data/site.json') + window.site = await data.json() + } + + return window.site + } +} diff --git a/_packs/controllers/scroll_controller.js b/_packs/controllers/scroll_controller.js index 5b168a5..e6a6874 100644 --- a/_packs/controllers/scroll_controller.js +++ b/_packs/controllers/scroll_controller.js @@ -1,5 +1,3 @@ -import 'core-js/stable' -import 'regenerator-runtime/runtime' import { Controller } from 'stimulus' /* diff --git a/_packs/controllers/search_controller.js b/_packs/controllers/search_controller.js index 57a57e5..a33b6ab 100644 --- a/_packs/controllers/search_controller.js +++ b/_packs/controllers/search_controller.js @@ -1,5 +1,3 @@ -import 'core-js/stable' -import 'regenerator-runtime/runtime' import { Controller } from 'stimulus' import { Liquid } from 'liquidjs' diff --git a/_packs/controllers/slider_controller.js b/_packs/controllers/slider_controller.js new file mode 100644 index 0000000..60a31c2 --- /dev/null +++ b/_packs/controllers/slider_controller.js @@ -0,0 +1,64 @@ +import { Controller } from 'stimulus' + +/* + * Slider con scroll automático + */ +export default class extends Controller { + static targets = [ 'control' ] + + connect () { + this.active(this.controlTargets.find(x => x.href.endsWith(window.location.hash))) + + this.interval = setInterval(() => this.inViewport ? this.controlTargets[this.next].click() : null, this.duration * 1000) + } + + get duration () { + const duration = parseInt(this.data.get('duration')) + + return isNaN(duration) ? 15 : duration + } + + disconnect () { + clearInterval(this.interval) + } + + active (control) { + if (!control) return + + this.controlTargets.forEach(other => other.classList.toggle('active', control.href === other.href)) + this.current = this.controlTargets.indexOf(control) + } + + activate (event) { + // XXX: En Firefox, el target del evento también puede ser el + // contenido del link :/ + let t = (event.target.href) ? event.target : event.target.parentElement + + this.active(t) + } + + get current () { + return parseInt(this.data.get('current')) || 0 + } + + set current (value) { + this.data.set('current', value) + } + + get next () { + const next = this.current + 1 + + return (this.controlTargets[next]) ? next : 0 + } + + get inViewport () { + const bounding = this.element.getBoundingClientRect(); + + return ( + bounding.top >= 0 && + bounding.left >= 0 && + bounding.bottom <= (window.innerHeight || document.documentElement.clientHeight) && + bounding.right <= (window.innerWidth || document.documentElement.clientWidth) + ); + }; +} diff --git a/_packs/entry.js b/_packs/entry.js index 8c6fcb5..5a9e1fa 100644 --- a/_packs/entry.js +++ b/_packs/entry.js @@ -1,3 +1,6 @@ +import 'core-js/stable' +import 'regenerator-runtime/runtime' + import { Application } from 'stimulus' import { definitionsFromContext } from "stimulus/webpack-helpers"