import { IgniteElement } from "../ignite-html/ignite-element.js"; import { IgniteTemplate, slot } from "../ignite-html/ignite-template.js"; /** * Adds a pull to refresh functionality to an IgniteTemplate. This template must have an overflow set for this to work. * @param {Function} refreshCallback A callback function that will be invoked when the pull to refresh is activated. * @param {IgniteTemplate} placeholderElement An optional element to display indicating a pull to refresh is supported. * @param {Number} maxPull Optional amount in pixels required to be pulled down before a refresh is triggered. * @returns {IgniteTemplate} This ignite template. */ IgniteTemplate.prototype.refresh = function(refreshCallback, placeholderElement = null, maxPull = 125) { this.refreshCallback = refreshCallback; this.refreshPlaceholderElement = placeholderElement; this.refreshTouchStartY = 0; if (placeholderElement && !(placeholderElement instanceof IgniteTemplate)) { throw "placeholderElement must be an IgniteTemplate."; } this.refreshTouchStartListener = (event) => { this.refreshTouchStartY = event.touches[0].clientY; this.refreshTouchStartTop = this.element.scrollTop; //Save the default overflow value if we don't have it yet. if (!this.refreshTouchOverflow) { this.refreshTouchOverflow = window.getComputedStyle(this.element).getPropertyValue("overflow-y"); } this.element.addEventListener("touchmove", this.refreshTouchMoveListener); this.element.addEventListener("touchend", this.refreshTouchEndListener); }; this.refreshTouchMoveListener = (event) => { var touch = event.touches[0]; var diff = touch.clientY - (this.refreshTouchStartY + this.refreshTouchStartTop + 15); if (diff < maxPull) { if (this.refreshPlaceholderElement instanceof IgniteTemplate) { this.refreshPlaceholderElement.element.style.setProperty("min-height", `${Math.max(diff, 0)}px`); this.refreshPlaceholderElement.element.style.setProperty("height", `${Math.max(diff, 0)}px`); } else { this.refreshPlaceholderElement.style.setProperty("min-height", `${Math.max(diff, 0)}px`); this.refreshPlaceholderElement.style.setProperty("height", `${Math.max(diff, 0)}px`); } } else { if (this.refreshPlaceholderElement instanceof IgniteTemplate) { this.refreshPlaceholderElement.element.style.setProperty("min-height", "0px"); this.refreshPlaceholderElement.element.style.setProperty("height", "0px"); } else { this.refreshPlaceholderElement.style.setProperty("min-height", "0px"); this.refreshPlaceholderElement.style.setProperty("height", "0px"); } this.element.removeEventListener("touchmove", this.refreshTouchMoveListener); this.element.removeEventListener("touchend", this.refreshTouchEndListener); this.element.style.removeProperty("overflow-y"); this.element.style.setProperty("overflow-y", this.refreshTouchOverflow, "important"); this.refreshCallback(); return; } if (diff > 0 && this.element.style["overflow-y"] != "hidden") { this.element.style.setProperty("overflow-y", "hidden", "important"); } }; this.refreshTouchEndListener = (event) => { if (this.refreshPlaceholderElement instanceof IgniteTemplate) { this.refreshPlaceholderElement.element.style.setProperty("min-height", "0px"); this.refreshPlaceholderElement.element.style.setProperty("height", "0px"); } else { this.refreshPlaceholderElement.style.setProperty("min-height", "0px"); this.refreshPlaceholderElement.style.setProperty("height", "0px"); } this.element.removeEventListener("touchmove", this.refreshTouchMoveListener); this.element.removeEventListener("touchend", this.refreshTouchEndListener); this.element.style.removeProperty("overflow-y"); this.element.style.setProperty("overflow-y", this.refreshTouchOverflow, "important"); }; this._constructors.push((parent, sibling) => { if (this.refreshCallback) { if (this.refreshPlaceholderElement) { this.refreshPlaceholderElement.construct(this.element, null); this.refreshPlaceholderElement.element.style.setProperty("min-height", "0px"); this.refreshPlaceholderElement.element.style.setProperty("height", "0px"); this.element.prepend(this.refreshPlaceholderElement.element); } else { this.refreshPlaceholderElement = this.element.querySelector("refresh-placeholder"); if (!this.refreshPlaceholderElement) { this.refreshPlaceholderElement = document.createElement("div"); this.refreshPlaceholderElement.classList.add("ignite-html"); this.refreshPlaceholderElement.classList.add("refresh-placeholder"); this.refreshPlaceholderElement.style.setProperty("min-height", "0px"); this.refreshPlaceholderElement.style.setProperty("height", "0px"); this.element.prepend(this.refreshPlaceholderElement); } else { this.refreshPlaceholderElement.style.setProperty("min-height", "0px"); this.refreshPlaceholderElement.style.setProperty("height", "0px"); } } this.element.addEventListener("touchstart", this.refreshTouchStartListener); } }); return this; }; /** * A placeholder element that can be used to customize the refresh placeholder location. */ class RefreshPlaceholder extends IgniteElement { render() { return this.template.child(new slot(this)); } } class RefreshPlaceholderTemplate extends IgniteTemplate { constructor(...children) { super("refresh-placeholder", children); } } IgniteHtml.register("refresh-placeholder", RefreshPlaceholder); export { RefreshPlaceholderTemplate as RefreshPlaceholder }