/* eslint-disable @typescript-eslint/no-unused-vars */ import { DataUtil, getObjectPropertyValueByKey, stringSnakeToCamel, getAttributeValueByBreakpoint, getViewPort, isVisibleElement, throttle, getCSS, ElementStyleUtil, } from "../_utils/index"; //import { CookieComponent } from "./_CookieComponent"; export interface ScrollOptions { saveState?: boolean; } const defaultScrollOptions: ScrollOptions = { saveState: true, }; class ScrollComponent { element: HTMLElement; options: ScrollOptions; id: string; constructor(_element: HTMLElement, options: ScrollOptions) { this.element = _element; this.options = Object.assign(defaultScrollOptions, options); this.id = this.element.getAttribute("id") || ""; this.update(); // this.element.setAttribute('data-kt-scrolltop', 'true') DataUtil.set(this.element, "scroll", this); } private getOption = (name: string) => { if (this.element.hasAttribute("data-kt-scroll-" + name) === true) { const attr = this.element.getAttribute("data-kt-scroll-" + name) || ""; let value: string | JSON | boolean = getAttributeValueByBreakpoint(attr); if (value !== null && String(value) === "true") { value = true; } else if (value !== null && String(value) === "false") { value = false; } return value; } else { const optionName = stringSnakeToCamel(name); const option = getObjectPropertyValueByKey(this.options, optionName); if (option) { return getAttributeValueByBreakpoint(option); } else { return null; } } }; private getHeightType = () => { if (this.getOption("height")) { return "height"; } if (this.getOption("min-height")) { return "min-height"; } if (this.getOption("max-height")) { return "max-height"; } }; private getAutoHeight = () => { let height: number | string = getViewPort().height; const dependencies = this.getOption("dependencies"); const wrappers = this.getOption("wrappers"); const offset = this.getOption("offset"); // Height dependencies if (dependencies !== null) { const elements = document.querySelectorAll(dependencies as string); if (elements && elements.length > 0) { for (let i = 0, len = elements.length; i < len; i++) { const element = elements[i] as HTMLElement; if (isVisibleElement(element) === false) { continue; } height = height - parseInt(getCSS(element, "height")); height = height - parseInt(getCSS(element, "margin-top")); height = height - parseInt(getCSS(element, "margin-bottom")); const borderTop = getCSS(element, "border-top"); if (borderTop) { height = height - parseInt(borderTop); } const borderBottom = getCSS(element, "border-bottom"); if (borderBottom) { height = height - parseInt(borderBottom); } } } } // Wrappers if (wrappers !== null) { const elements = document.querySelectorAll(wrappers as string); if (elements && elements.length > 0) { for (let i = 0, len = elements.length; i < len; i++) { const element = elements[i] as HTMLElement; if (!isVisibleElement(element)) { continue; } height = height - parseInt(getCSS(element, "margin-top")); height = height - parseInt(getCSS(element, "margin-bottom")); height = height - parseInt(getCSS(element, "padding-top")); height = height - parseInt(getCSS(element, "padding-bottom")); const borderTop = getCSS(element, "border-top"); if (borderTop) { height = height - parseInt(borderTop); } const borderBottom = getCSS(element, "border-bottom"); if (borderBottom) { height = height - parseInt(borderBottom); } } } } // Custom offset if (offset !== null) { height = height - parseInt(offset as string); } height = height - parseInt(getCSS(this.element, "margin-top")); height = height - parseInt(getCSS(this.element, "margin-bottom")); const borderTop = getCSS(this.element, "border-top"); if (borderTop) { height = height - parseInt(borderTop); } const borderBottom = getCSS(this.element, "border-bottom"); if (borderBottom) { height = height - parseInt(borderBottom); } height = String(height) + "px"; return height; }; private setupHeight = () => { const height = this.getHeight(); const heightType = this.getHeightType() as string; // Set height if (height !== null && height.length > 0) { ElementStyleUtil.set(this.element, heightType, height); } else { ElementStyleUtil.set(this.element, heightType, ""); } }; private setupState = () => { if (this.getOption("save-state") === true && this.id) { // const cookie = CookieComponent.get(this.id + "st"); // if (cookie) { // const pos = parseInt(cookie); // if (pos > 0) { // this.element.scrollTop = pos; // } // } } }; private setupScrollHandler = () => { if (this.getOption("save-state") === true && this.id) { this.element.addEventListener("scroll", this.scrollHandler); } else { this.element.removeEventListener("scroll", this.scrollHandler); } }; private scrollHandler = () => { const cookieId = this.id + "st"; //CookieComponent.set(cookieId, this.element.scrollTop, {}); }; private destroyScrollHandler = () => { this.element.removeEventListener("scroll", this.scrollHandler); }; private resetHeight = () => { const heghtType = this.getHeightType(); if (heghtType) { ElementStyleUtil.set(this.element, heghtType, ""); } }; /////////////////////// // ** Public API ** // /////////////////////// public update = () => { // Activate/deactivate if ( this.getOption("activate") === true || !this.element.hasAttribute("data-kt-scroll-activate") ) { this.setupHeight(); this.setupScrollHandler(); this.setupState(); } else { this.resetHeight(); this.destroyScrollHandler(); } }; public getHeight = () => { const heightType = this.getHeightType(); const height = this.getOption(heightType || ""); if (height instanceof Function) { return height.call(height); } else if ( height !== null && typeof height === "string" && height.toLowerCase() === "auto" ) { return this.getAutoHeight(); } else { return height; } }; public getElement = () => { return this.element; }; // Static methods public static hasInstace(element: HTMLElement) { return DataUtil.has(element, "scroll"); } public static getInstance(element: HTMLElement): ScrollComponent | undefined { if (element !== null && ScrollComponent.hasInstace(element)) { const data = DataUtil.get(element, "scroll"); if (data) { return data as ScrollComponent; } } } // Create Instances public static createInstances(selector: string) { const elements = document.body.querySelectorAll(selector); elements.forEach((element: Element) => { const item = element as HTMLElement; let scroll = ScrollComponent.getInstance(item); if (!scroll) { scroll = new ScrollComponent(item, defaultScrollOptions); } }); } public static destroyAll(attr: string = '[data-kt-scroll="true"]') {} public static bootstrap(attr: string = '[data-kt-scroll="true"]') { ScrollComponent.createInstances(attr); ScrollComponent.resize(); } public static createInstance = ( element: HTMLElement, options: ScrollOptions = defaultScrollOptions ): ScrollComponent | undefined => { let scroll = ScrollComponent.getInstance(element); if (!scroll) { scroll = new ScrollComponent(element, options); } return scroll; }; public static reinitialization(attr: string = '[data-kt-scroll="true"]') { ScrollComponent.createInstances(attr); } public static updateAll() { const elements = document.body.querySelectorAll('[data-kt-scroll="true"]'); elements.forEach((element: Element) => { const instance = ScrollComponent.getInstance(element as HTMLElement); if (instance) { instance.update(); } }); } public static resize() { // Window Resize Handling window.addEventListener("resize", function () { let timer; throttle( timer, () => { // Locate and update Drawer instances on window resize ScrollComponent.updateAll(); }, 200 ); }); } } export { ScrollComponent, defaultScrollOptions };