import { displayName, escapeSearchHtml, formatSearchPrice, loadSearchCatalog, searchCatalogProducts, } from "/js/search-catalog.js?v=persianCopyRtl2"; const PREVIEW_COUNT = 4; const MIN_CHARS = 2; const DEBOUNCE_MS = 180; function debounce(fn, ms) { let t = 0; return (...args) => { window.clearTimeout(t); t = window.setTimeout(() => fn(...args), ms); }; } function suggestItemHtml(p) { const title = displayName(p); const href = `/products/${escapeSearchHtml(p.slug)}/`; const img = p.heroImage ? `` : ``; return ` ${img} ${escapeSearchHtml(title)} ${formatSearchPrice(p.price)} `; } function bindSearchInput(input, panel) { if (!input || !panel) return; let products = null; let active = -1; loadSearchCatalog() .then((list) => { products = list; }) .catch(() => { products = []; }); function close() { panel.hidden = true; panel.innerHTML = ""; active = -1; input.setAttribute("aria-expanded", "false"); } function open() { panel.hidden = false; input.setAttribute("aria-expanded", "true"); } function render(q) { if (!products) return; const hits = searchCatalogProducts(products, q, PREVIEW_COUNT); if (!hits.length) { close(); return; } const allHref = `/search/?q=${encodeURIComponent(q.trim())}`; panel.innerHTML = hits.map(suggestItemHtml).join("") + `مشاهده همه نتایج`; open(); active = -1; } const onInput = debounce(() => { const q = input.value.trim(); if (q.length < MIN_CHARS) { close(); return; } render(q); }, DEBOUNCE_MS); input.addEventListener("input", onInput); input.addEventListener("focus", () => { const q = input.value.trim(); if (q.length >= MIN_CHARS) render(q); }); input.addEventListener("keydown", (e) => { const items = [...panel.querySelectorAll(".search-suggest-item, .search-suggest-all")]; if (!items.length || panel.hidden) return; if (e.key === "ArrowDown") { e.preventDefault(); active = Math.min(active + 1, items.length - 1); items.forEach((el, i) => el.classList.toggle("is-active", i === active)); items[active]?.scrollIntoView({ block: "nearest" }); } else if (e.key === "ArrowUp") { e.preventDefault(); active = Math.max(active - 1, 0); items.forEach((el, i) => el.classList.toggle("is-active", i === active)); items[active]?.scrollIntoView({ block: "nearest" }); } else if (e.key === "Enter" && active >= 0) { e.preventDefault(); items[active].click(); } else if (e.key === "Escape") { close(); input.blur(); } }); document.addEventListener("click", (e) => { if (!(e.target instanceof Element)) return; if (input.contains(e.target) || panel.contains(e.target)) return; close(); }); } export function initSearchSuggest() { document.querySelectorAll(".search-shell").forEach((shell) => { const input = shell.querySelector('input[type="search"]'); const panel = shell.querySelector("[data-search-suggest]"); bindSearchInput(input, panel); }); document.querySelectorAll(".mobile-search").forEach((form) => { const input = form.querySelector('input[type="search"]'); let panel = form.querySelector("[data-search-suggest]"); if (!panel) { panel = document.createElement("div"); panel.className = "search-suggest search-suggest--mobile"; panel.setAttribute("data-search-suggest", ""); panel.hidden = true; form.appendChild(panel); } bindSearchInput(input, panel); }); const params = new URLSearchParams(location.search); const q = params.get("q"); if (q && location.pathname.replace(/\/+$/, "").endsWith("/search")) { document.querySelectorAll('.search-form input[name="q"], .mobile-search input[name="q"]').forEach((input) => { input.value = q; }); } }