@ribajs/shopify
Version:
Shopify extension for Riba.js
95 lines (82 loc) • 2.48 kB
text/typescript
import { Component, TemplateFunction } from "@ribajs/core";
import { Pjax, Prefetch } from "@ribajs/router";
export class ShopifyProductScrollbarComponent extends Component {
public static tagName = "shopify-product-scrollbar";
static get observedAttributes(): string[] {
return [];
}
public scope: any = {
onScroll: this.onScroll,
onProductTap: this.onProductTap,
onProductMouseenter: this.onProductMouseenter,
title: "",
};
protected products: NodeListOf<HTMLElement> | null = null;
constructor() {
super();
}
/**
* Default custom Element method
* Invoked when the custom element is first connected to the document's DOM.
*/
protected connectedCallback() {
super.connectedCallback();
this.products = this.querySelectorAll(".embed-responsive");
this.init(ShopifyProductScrollbarComponent.observedAttributes);
}
/**
* Just open the product url
*/
public onProductTap(event: Event, scope: any, eventEl: HTMLElement) {
const url = eventEl.dataset.url;
if (!url) {
return;
}
const pjax = Pjax.getInstance("main");
if (!pjax) {
return;
}
pjax.goTo(url);
}
/**
* Preload product on mouse over
*/
public onProductMouseenter(event: Event, scope: any, eventEl: HTMLElement) {
const url = eventEl.dataset.url;
const prefetch = Prefetch.getInstance();
if (!prefetch) {
return;
}
if (!url) {
return;
}
prefetch.onLinkEnter(url, eventEl as HTMLAnchorElement, event);
}
/**
* get product in the middle of the scrollbar element
*/
public onScroll(event: Event, scope: any, eventEl: HTMLElement) {
if (this.products) {
for (let i = 0; i < this.products.length; i++) {
const product = this.products[i];
const productData = product.dataset;
const parentRect = eventEl.getBoundingClientRect();
const elementRect = product.getBoundingClientRect();
const elementMiddle = elementRect.width / 2;
/** centerX is 0 if the product is in the middle */
const centerX =
elementRect.left - (parentRect.width / 2 - elementMiddle);
const offset = elementMiddle;
if (centerX > offset * -1 && centerX < offset) {
this.scope.title = productData.title;
}
}
}
}
protected requiredAttributes(): string[] {
return [];
}
protected template(): ReturnType<TemplateFunction> {
return null;
}
}