UNPKG

@salla.sa/twilight-components

Version:
228 lines (223 loc) 10.7 kB
/*! * Crafted with ❤ by Salla */ import { proxyCustomElement, HTMLElement, h } from '@stencil/core/internal/client'; import { K as KeyBoardArrowLeftIcon, a as KeyBoardArrowRightIcon } from './keyboard_arrow_left.js'; const sallaBreadcrumbCss = ":host{display:block}"; const SallaBreadcrumb$1 = /*@__PURE__*/ proxyCustomElement(class SallaBreadcrumb extends HTMLElement { constructor() { super(); this.__registerHost(); var _a, _b; this.sessionStorageKey = "breadcrumb_snapshot"; this.itemSlot = ((_a = this.host.querySelector('[slot="item"]')) === null || _a === void 0 ? void 0 : _a.outerHTML) || `<li class="s-breadcrumb-item"><a href={url}>{title}</a></li>`; this.iconSlot = (_b = this.host.querySelector('[slot="icon"]')) === null || _b === void 0 ? void 0 : _b.outerHTML; } componentWillLoad() { return (new Promise(resolve => salla.onReady(() => salla.lang.onLoaded(resolve)))) .then(() => { if (salla.url.is_page('index')) { throw new Error('salla-breadcrumb:: breadcrumb not supported on home page'); } }) .then(() => { if (!salla.config.get('theme.settings.is_breadcrumbs_enabled', true)) { throw new Error('salla-breadcrumb:: merchant disabled the feature'); } }) .then(() => { var _a; const page = salla.config.get("page"); if (!page || !page.slug) { salla.logger.error('salla-breadcrumbs:: page object not existed on salla.config.get("page")!'); this.breadcrumbs = []; return; } let sessionBreadcrumbs = this.getSessionBreadcrumbs(); if (page.slug === "product.single" && sessionBreadcrumbs && sessionBreadcrumbs.length > 0) { sessionBreadcrumbs.push({ title: page.title, url: page.url }); this.breadcrumbs = this.setBreadcrumbsFromArray(sessionBreadcrumbs); this.storeBreadcrumbSnapshot(); } else if (sessionBreadcrumbs && sessionBreadcrumbs.length > 0) { if (this.isNewPage(page, sessionBreadcrumbs)) { this.breadcrumbs = this.generateBreadcrumbs(page); this.storeBreadcrumbSnapshot(); } else { this.breadcrumbs = this.setBreadcrumbsFromArray(sessionBreadcrumbs); } } else { this.breadcrumbs = this.generateBreadcrumbs(page); this.storeBreadcrumbSnapshot(); } if ((_a = this.breadcrumbs) === null || _a === void 0 ? void 0 : _a.length) { this.breadcrumbs[this.breadcrumbs.length - 1].is_last = true; } return this.breadcrumbs; }) .catch((error) => { salla.logger.error('salla-breadcrumb:: unexpected error!', error); this.breadcrumbs = []; }); } getSessionBreadcrumbs() { if (new URLSearchParams(window.location.search).get('from') === 'search-bar') { return []; } return JSON.parse(sessionStorage.getItem(this.sessionStorageKey) || '[]'); } /** * Helper function to determine if we're navigating to a new page that requires updating the session storage. */ isNewPage(page, sessionBreadcrumbs) { // Check if the last breadcrumb in sessionStorage matches the current page's URL. const lastBreadcrumb = sessionBreadcrumbs[sessionBreadcrumbs.length - 1]; return (lastBreadcrumb === null || lastBreadcrumb === void 0 ? void 0 : lastBreadcrumb.url) !== page.url; // If the URLs don't match, it's a new page. } setBreadcrumbsFromArray(breadcrumbArray) { return breadcrumbArray.map((item, index) => (Object.assign(Object.assign({}, item), { is_last: index === breadcrumbArray.length - 1 }))); } /** * Sanitizes the breadcrumb title by splitting it on the `|` character and returning * the part based on `preferedIndex`. If no separator is found, returns the trimmed title. * * @param {string} title - The title to sanitize. * @param {number} [preferedIndex=1] - Index of the part to return (0 for first, 1 for second). * @returns {string} - The sanitized title. */ sanitizeBreadcrumbTitle(title, preferedIndex = 1) { if (!title.includes('|')) { return title.trim(); } return title.split('|').map(part => part.trim())[preferedIndex]; } generateBreadcrumbs(page) { var _a, _b; let breadcrumbs = []; //TODO:: check what is the need from this? if (page.slug === 'product.single') { const previousPage = this.getSessionBreadcrumbs(); if (previousPage.length > 0 && ((_a = previousPage[1]) === null || _a === void 0 ? void 0 : _a.url) === ((_b = page.parent) === null || _b === void 0 ? void 0 : _b.url)) { return this.setBreadcrumbsFromArray([...previousPage, page]); } } // Start with the current page let currentPage = page; // Traverse up to the parent pages while (currentPage) { if (currentPage.title) { breadcrumbs.unshift({ title: currentPage.title, url: currentPage.url, }); } currentPage = currentPage.parent; } // Additional logic based on page slug or title if (page.slug.includes("customer") && page.slug !== 'customer.profile') { breadcrumbs.unshift({ title: salla.lang.get('common.titles.profile'), url: salla.url.get('profile') }); } if (page.slug.includes('blog')) { breadcrumbs.unshift({ title: salla.lang.get('blocks.footer.blog'), url: salla.url.get('blog') }); } if (page.slug === 'brands.single') { breadcrumbs.unshift({ title: salla.lang.get('common.titles.brands'), url: salla.url.get('brands') }); } if (!page.title && page.slug === 'loyalty') { breadcrumbs.unshift({ title: salla.lang.get('common.titles.loyalty_program'), url: salla.url.get('loyalty') }); } // Add home breadcrumb breadcrumbs.unshift({ title: salla.lang.get('common.titles.home'), url: salla.url.get('') }); return breadcrumbs; } storeBreadcrumbSnapshot() { try { const page = salla.config.get("page"); // Skip storing breadcrumbs for product.single page if ((page === null || page === void 0 ? void 0 : page.slug) === 'product.single') { return; } const items = [...this.breadcrumbs]; // Find the last item and update its URL const lastItemIndex = items.length - 1; if (lastItemIndex >= 0) { items[lastItemIndex].url = window.location.href; } const breadcrumbSnapshot = JSON.stringify(items); sessionStorage.setItem(this.sessionStorageKey, breadcrumbSnapshot); } catch (error) { salla.logger.error('salla-breadcrumb:: Failed to store breadcrumb snapshot in sessionStorage.', error); } } render() { if (this.breadcrumbs.length <= 1) { salla.log('salla-breadcrumb:: There is no breadcrumbs!'); return null; } return (h("ol", { class: { "s-breadcrumb-wrapper": true, "s-breadcrumb-dark": salla.url.is_page('loyalty'), "s-breadcrumb-primary-reverse": salla.config.get('page.slug').includes('customer') } }, this.breadcrumbs.map(item => { const isProductSingle = salla.config.get('page.slug') === "product.single"; const title = (isProductSingle && item.is_last) ? item.title : this.sanitizeBreadcrumbTitle(item.title); const itemHTML = this.itemSlot.replace(/\{url\}/g, item.url).replace(/\{title\}/g, title); return [ h("div", { class: "s-breadcrumb-slot", innerHTML: itemHTML }), this.getArrowDomForItem(item) ]; }))); } getArrowDomForItem(item) { if (item.is_last) { return ''; } let iconDom = this.iconSlot || (salla.config.get('theme.is_rtl', true) ? KeyBoardArrowLeftIcon : KeyBoardArrowRightIcon); return h("li", { class: "s-breadcrumb-arrow" }, h("div", { class: { "s-breadcrumb-icon-slot": true, "s-breadcrumb-default-icon": !this.iconSlot }, innerHTML: iconDom })); } /** * Lifecycle method called after the component is rendered. * - Reduces the number of elements in the DOM. * - Removes unnecessary slots parent elements. * - Replaces the last anchor tag in the breadcrumb with its content. */ componentDidRender() { var _a, _b, _c; // Reduces the number of elements in the DOM this.host.querySelectorAll('.s-breadcrumb-slot').forEach(el => el.replaceWith(el.firstChild)); this.host.querySelectorAll('.s-breadcrumb-icon-slot.s-breadcrumb-default-icon').forEach(el => el.replaceWith(el.querySelector('svg'))); // Removes the slots parent elements if exists (_a = this.host.querySelector('[slot="item"]')) === null || _a === void 0 ? void 0 : _a.remove(); (_b = this.host.querySelector('[slot="icon"]')) === null || _b === void 0 ? void 0 : _b.remove(); let lastEl = (_c = this.host.querySelectorAll('.s-breadcrumb-item')[this.breadcrumbs.length - 1]) === null || _c === void 0 ? void 0 : _c.querySelector('a'); lastEl && lastEl.replaceWith(lastEl.firstChild); } get host() { return this; } static get style() { return sallaBreadcrumbCss; } }, [0, "salla-breadcrumb", { "breadcrumbs": [32] }]); function defineCustomElement$1() { if (typeof customElements === "undefined") { return; } const components = ["salla-breadcrumb"]; components.forEach(tagName => { switch (tagName) { case "salla-breadcrumb": if (!customElements.get(tagName)) { customElements.define(tagName, SallaBreadcrumb$1); } break; } }); } const SallaBreadcrumb = SallaBreadcrumb$1; const defineCustomElement = defineCustomElement$1; export { SallaBreadcrumb, defineCustomElement }; //# sourceMappingURL=salla-breadcrumb.js.map //# sourceMappingURL=salla-breadcrumb.js.map