{"version":3,"file":"ScrollNavigation.js","names":["ScrollNavigation","a","setters","Component","default","deepMerge","on","off","trigger","execute","constructor","element","options","arguments","length","classNames","activeElement","scrollBehavior","scrollTopOffset","horizontalScrollOffset","initCache","selectors","navigationButtons","querySelectorAll","sections","scrollable","querySelector","afterInit","initObserver","bindEvents","onClick","bind","e","targetElement","target","closest","setActive","sectionId","getAttribute","section","focusOnSection","scrollToSection","sectionAnchor","focus","state","activeNavElement","classList","remove","add","scrollToNavigationElement","window","scroll","top","offsetTop","behavior","offset","observer","IntersectionObserver","onObserve","observerOptions","forEach","observe","entries","entry","isIntersecting","navigationItem","destroy"],"sources":["components/global/ScrollNavigation.js"],"sourcesContent":["import Component from 'core/Component';\nimport { deepMerge } from 'toolbox/deepMerge';\nimport { on, off, trigger } from 'toolbox/event';\n\n/**\n * This is a description of the ScrollNavigation constructor function.\n * @class\n * @classdesc This is a description of the ScrollNavigation class. (must be edited)\n * @extends Component\n */\nexport default class ScrollNavigation extends Component {\n    /**\n     * Constructor of the class that mainly merge the options of the components\n     * @param {HTMLElement} element HTMLElement of the component\n     * @param {object} options options that belongs to the component\n     */\n    constructor(element, options = {}) {\n        super(element, deepMerge({\n            classNames: {\n                activeElement: 'm-active',\n            },\n            scrollBehavior: 'smooth', // Specifies whether the scrolling should animate smoothly (smooth), happen instantly in a single jump (instant), or let the browser choose (auto, default).\n            scrollTopOffset: 120, // Change the edge offset If you have a fixed navigation bar\n            horizontalScrollOffset: 40,\n        }, options));\n    }\n\n    /**\n     * All selectors must be cached. Never cache elements that are out of the component scope\n     */\n    initCache() {\n        this.selectors.navigationButtons = this.element.querySelectorAll('[data-js-nav-button]');\n        this.selectors.sections = this.element.querySelectorAll('[data-js-section-id]');\n        this.selectors.scrollable = this.element.querySelector('[data-component=\"global/Scrollable\"]');\n    }\n\n    /**\n     * This hook is used for any action that should be performed after the component init\n     */\n    afterInit() {\n        this.initObserver();\n    }\n\n    /**\n     * Should contain only event listeners and nothing else\n     * All the event handlers should be into a separated function. No usage of anonyous function\n     */\n    bindEvents() {\n        on('click', this.selectors.navigationButtons, this.onClick.bind(this));\n    }\n\n    /**\n    * 'click' handler for navigation item. Scrolls page to related section\n    * @param {EventObject} e - event object\n    */\n    onClick(e) {\n        let targetElement = e.target;\n\n        if (targetElement) {\n            targetElement = targetElement.closest('[data-js-nav-item-id]');\n        }\n\n        if (!targetElement) {\n            return;\n        }\n\n        this.setActive(targetElement);\n        const sectionId = targetElement.getAttribute('data-js-nav-item-id');\n        const section = this.element.querySelector(`[data-js-section-id=\"${sectionId}\"]`);\n        if (section) {\n            this.focusOnSection(sectionId);\n            this.scrollToSection(section);\n        }\n    }\n\n    /**\n     * Focus to a specified section\n     * @param {String} sectionId section element to focus\n     */\n    focusOnSection(sectionId) {\n        const sectionAnchor = this.element.querySelector(`[data-anchor-section-id=\"${sectionId}\"]`);\n\n        if (sectionAnchor) {\n            sectionAnchor.focus();\n        }\n    }\n\n    /**\n    * Sets specified navigation item as active\n    * @param {HTMLElement} targetElement - navigation item element\n    */\n    setActive(targetElement) {\n        if (!targetElement) {\n            return;\n        }\n        if (this.state.activeNavElement) {\n            this.state.activeNavElement.classList.remove(this.options.classNames.activeElement);\n        }\n        targetElement.classList.add(this.options.classNames.activeElement);\n        this.state.activeNavElement = targetElement;\n        this.scrollToNavigationElement(targetElement);\n    }\n\n    /**\n     * Scrolls to a specified section\n     * @param {HTMLElement} section section element to scroll to\n     */\n    scrollToSection(section) {\n        window.scroll({\n            top: section.offsetTop - this.options.scrollTopOffset,\n            behavior: this.options.scrollBehavior,\n        });\n    }\n\n    /**\n     * Scroll to the active navigation element\n     * @param {HTMLElement} element - navigation element\n     */\n    scrollToNavigationElement(element) {\n        if (this.selectors.scrollable) {\n            trigger('scrollable.scrollToElement', this.selectors.scrollable, { element, offset: this.options.horizontalScrollOffset });\n        }\n    }\n\n    /**\n     * Initialize IntersectionObserver for sections\n     */\n    initObserver() {\n        this.observer = new window.IntersectionObserver(this.onObserve.bind(this), this.options.observerOptions);\n        this.selectors.sections.forEach(this.observer.observe.bind(this.observer));\n    }\n\n    /**\n     * Update active navigation item when observed section appears in view port.\n     *\n     * @param {Object[]} entries IntersectionObserverEntry objects\n     */\n    onObserve(entries) {\n        entries.forEach((entry) => {\n            if (entry.isIntersecting) {\n                const sectionId = entry.target.getAttribute('data-js-section-id');\n                const navigationItem = this.element.querySelector(`[data-js-nav-item-id=\"${sectionId}\"]`);\n                this.setActive(navigationItem);\n            }\n        });\n    }\n\n    /**\n     * Destroy is called automatically after the component is being removed from the DOM\n     * You must always destroy the listeners attached to an element to avoid any memory leaks\n     */\n    destroy() {\n        off('click', this.selectors.navigationButtons);\n    }\n}\n"],"mappings":"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","ignoreList":[]}