(function () {
var PER_PAGE = 24;
var mq = window.matchMedia('(max-width:767px)');
function init() {
var page = document.querySelector('.tc-page');
if (!page || page.dataset.tcInit) return;
page.dataset.tcInit = '1';
if (document.body.classList.contains('elementor-editor-active')) return;
var filters = page.querySelector('.tc-filters');
var openBtn = page.querySelector('.tc-open-filters');
var badge = page.querySelector('.tc-badge');
var sheet = page.querySelector('.tc-sheet');
// Only write when the text changes, so our own updates don't re-trigger the MutationObserver below.
function setText(el, text) { if (el.textContent !== text) el.textContent = text; }
// --- Result count ("Showing 1–24 of 36 products") from JetSmartFilters' query props.
function props() {
var s = window.JetSmartFilterSettings;
var p = s && s.props && s.props['epro-loop-builder'];
return p && (p['default'] || p[Object.keys(p)[0]]);
}
function updateCount() {
var p = props();
if (!p) return;
var total = parseInt(p.found_posts, 10) || 0;
var current = parseInt(p.page, 10) || 1;
var from = total ? (current - 1) * PER_PAGE + 1 : 0;
var to = Math.min(current * PER_PAGE, total);
var label = total ? 'Showing ' + from + '–' + to + ' of ' + total + ' products' : 'No products found';
var show = 'Show ' + total + (total === 1 ? ' product' : ' products');
page.querySelectorAll('.tc-count').forEach(function (el) { setText(el, label); });
page.querySelectorAll('.tc-show-n').forEach(function (el) { setText(el, show); });
}
// --- Active filters: badge on the mobile Filter button, hide the "Now shopping by" block when empty.
function updateActive() {
var n = page.querySelectorAll('.tc-active .jet-active-filter').length;
page.classList.toggle('tc-has-active', n > 0);
if (badge) { if (badge.hidden !== !n) badge.hidden = !n; setText(badge, String(n)); }
}
// --- Collapsible filter sections (chevron on each filter title).
function setupCollapsibles() {
page.querySelectorAll('.tc-filter').forEach(function (w) {
var lbl = w.querySelector('.jet-filter-label');
if (!lbl || lbl.dataset.tcToggle) return;
lbl.dataset.tcToggle = '1';
lbl.setAttribute('role', 'button');
lbl.setAttribute('tabindex', '0');
var hasChecked = !!w.querySelector('input:checked');
var collapsed = mq.matches && !w.classList.contains('tc-open-mobile') && !hasChecked;
w.classList.toggle('is-collapsed', collapsed);
lbl.setAttribute('aria-expanded', collapsed ? 'false' : 'true');
function toggle() {
var c = !w.classList.contains('is-collapsed');
w.classList.toggle('is-collapsed', c);
lbl.setAttribute('aria-expanded', c ? 'false' : 'true');
}
lbl.addEventListener('click', toggle);
lbl.addEventListener('keydown', function (e) { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); toggle(); } });
});
}
// --- Mobile filter overlay.
function openFilters() {
page.classList.add('tc-filters-open');
document.documentElement.classList.add('tc-lock');
if (openBtn) openBtn.setAttribute('aria-expanded', 'true');
var close = filters.querySelector('.tc-close');
if (close) close.focus();
}
function closeFilters() {
page.classList.remove('tc-filters-open');
document.documentElement.classList.remove('tc-lock');
if (openBtn) { openBtn.setAttribute('aria-expanded', 'false'); openBtn.focus(); }
}
if (openBtn) openBtn.addEventListener('click', openFilters);
page.querySelectorAll('.tc-close, .tc-show-n').forEach(function (b) { b.addEventListener('click', closeFilters); });
page.querySelectorAll('.tc-clear-all').forEach(function (b) {
b.addEventListener('click', function () {
var btn = page.querySelector('.tc-clear .jet-remove-all-filters__button');
if (btn) btn.click();
});
});
// --- Mobile sort sheet, driven by the JetSmartFilters sorting select.
var select = page.querySelector('.tc-sort select');
// Sort through WooCommerce's ?orderby= URL (a normal page load) instead of JetSmartFilters' AJAX sort,
// whose request the site firewall blocks. Same order as the options in the sorting widget.
var ORDERBY = ['', 'popularity', 'date', 'popularity', 'price', 'price-desc', 'title', 'title-desc'];
if (select) {
var currentSort = new URLSearchParams(location.search).get('orderby') || '';
var sortIdx = ORDERBY.indexOf(currentSort);
if (sortIdx > 0) {
select.selectedIndex = sortIdx;
// Show the active sort, but give JetSmartFilters an empty value so its AJAX requests carry no
// sort JSON (the firewall blocks those); the server keeps the ?orderby= order for filtered results.
select.options[sortIdx].value = '';
}
page.addEventListener('change', function (e) {
if (e.target !== select) return;
e.stopImmediatePropagation();
var url = new URL(location.href);
var v = ORDERBY[select.selectedIndex] || '';
if (v) url.searchParams.set('orderby', v); else url.searchParams.delete('orderby');
url.searchParams.delete('paged');
url.pathname = url.pathname.replace(/\/page\/\d+\/?$/, '/');
location.href = url.toString();
}, true);
}
// Figma search placeholder.
var searchInput = page.querySelector('.tc-search .jet-search-filter__input');
if (searchInput) searchInput.placeholder = 'Search products';
// Figma breadcrumb separator.
var crumbs = page.querySelector('.tc-crumbs .woocommerce-breadcrumb');
if (crumbs) crumbs.childNodes.forEach(function (n) { if (n.nodeType === 3) n.textContent = n.textContent.replace(/(^|\s)\/(\s|$)/g, ' \u203A '); });
function closeSheet() { if (sheet) { sheet.hidden = true; document.documentElement.classList.remove('tc-lock'); } }
function openSheet() {
if (!sheet || !select) return;
var list = sheet.querySelector('.tc-sheet__list');
list.innerHTML = '';
Array.prototype.forEach.call(select.options, function (o, i) {
var b = document.createElement('button');
b.type = 'button';
b.className = 'tc-sheet__opt';
b.setAttribute('role', 'radio');
b.setAttribute('aria-checked', select.selectedIndex === i ? 'true' : 'false');
b.textContent = o.textContent.trim().replace(/^Sort by /i, '').replace(/^\w/, function (c) { return c.toUpperCase(); });
b.addEventListener('click', function () {
select.selectedIndex = i;
select.dispatchEvent(new Event('change', { bubbles: true })); // native event: JetSmartFilters listens with addEventListener
closeSheet();
});
list.appendChild(b);
});
sheet.hidden = false;
document.documentElement.classList.add('tc-lock');
var cur = list.querySelector('[aria-checked="true"]');
if (cur) cur.focus();
}
var sortBtn = page.querySelector('.tc-open-sort');
if (sortBtn) sortBtn.addEventListener('click', openSheet);
if (sheet) sheet.querySelectorAll('.tc-sheet__scrim, .tc-sheet__close').forEach(function (b) { b.addEventListener('click', closeSheet); });
document.addEventListener('keydown', function (e) {
if (e.key !== 'Escape') return;
if (sheet && !sheet.hidden) closeSheet();
else if (page.classList.contains('tc-filters-open')) closeFilters();
});
// Hide filters with no options for this category, and the pill row when only "All" is left.
function hideEmpty() {
function shown(el) { return el.offsetParent !== null || getComputedStyle(el).display !== 'none'; }
page.querySelectorAll('.tc-filter').forEach(function (w) {
var rows = w.querySelectorAll('.jet-checkboxes-list__row');
var any = Array.prototype.some.call(rows, function (r) { return getComputedStyle(r).display !== 'none'; });
w.classList.toggle('tc-empty', !any);
});
var pills = page.querySelector('.tc-pills');
if (pills) {
var n = Array.prototype.filter.call(pills.querySelectorAll('.jet-radio-list__row'), function (r) { return getComputedStyle(r).display !== 'none'; }).length;
pills.classList.toggle('tc-empty', n ul'), a = li.querySelector('.toggle-arrow');
if (!ul || !a) return;
var open = getComputedStyle(ul).display !== 'none';
if (a.classList.contains('tc-open') !== open) a.classList.toggle('tc-open', open);
});
}
page.addEventListener('click', function (e) { if (e.target.closest('.tc-cats .toggle-arrow')) setTimeout(syncCatArrows, 450); });
// Only the branch that contains the current category starts open (Figma); the others are collapsed.
(function collapseOtherCats() {
var here = location.pathname.replace(/\/page\/\d+\/?$/, '/');
page.querySelectorAll('.tc-cats .has-children').forEach(function (li) {
var ul = li.querySelector(':scope > ul');
if (!ul) return;
var inPath = Array.prototype.some.call(li.querySelectorAll('a.category-link'), function (link) {
try { return here.indexOf(new URL(link.href).pathname) === 0; } catch (err) { return false; }
});
if (!inPath) li.classList.add('collapsed'); // same class the category shortcode toggles
});
})();
function refresh() { updateCount(); updateActive(); setupCollapsibles(); hideEmpty(); syncCatArrows(); }
refresh();
// JetSmartFilters re-renders the grid and filters over AJAX; refresh after each update.
var t;
new MutationObserver(function () { clearTimeout(t); t = setTimeout(refresh, 60); }).observe(page, { childList: true, subtree: true });
if (window.JetSmartFilters && JetSmartFilters.events && JetSmartFilters.events.subscribe) {
JetSmartFilters.events.subscribe('ajaxFilters/updated', function () { setTimeout(refresh, 0); });
}
}
if (document.readyState !== 'loading') init(); else document.addEventListener('DOMContentLoaded', init);
window.addEventListener('load', init);
})();