/**
* Atabaque Jair — Frete Top 3
* Colapsa as opções de frete, mostrando apenas as 3 mais baratas.
* Cole este código em: Divi > Tema > Opções do Tema > Integrações > Código no
* OU adicione via Code Snippets como "JavaScript" (rodando no frontend).
*
* Compatível com WooCommerce + qualquer plugin de frete (Melhor Envio, Braspress, etc.)
*/
(function () {
/* ── Configurações ── */
const MAX_VISIBLE = 3; // quantas opções mostrar por padrão
const LABEL_MAIS = '▼ Ver todas as opções de envio';
const LABEL_MENOS = '▲ Mostrar menos';
/* ── Injeção de estilos ── */
const css = `
.frete-oculto {
display: none !important;
}
.frete-toggle-btn {
display: block;
width: 100%;
margin-top: 8px;
padding: 9px 14px;
background: transparent;
border: 1px solid #b89b6a;
border-radius: 6px;
color: #b89b6a;
font-size: 13px;
font-family: inherit;
cursor: pointer;
text-align: center;
transition: background .2s, color .2s;
}
.frete-toggle-btn:hover {
background: #b89b6a;
color: #fff;
}
`;
const styleEl = document.createElement('style');
styleEl.textContent = css;
document.head.appendChild(styleEl);
/* ── Função principal ── */
function collapseShipping() {
/**
* O WooCommerce renderiza as opções de frete como:
*
*
* Precisamos:
* 1. Extrair o preço de cada
* 2. Ordenar do mais barato ao mais caro
* 3. Esconder os que estão além de MAX_VISIBLE
* 4. Adicionar botão de toggle
*/
const lists = document.querySelectorAll('ul.woocommerce-shipping-rates, ul#shipping_method');
if (!lists.length) return;
lists.forEach(function (ul) {
/* Evita processar duas vezes */
if (ul.dataset.freteProcessed) return;
ul.dataset.freteProcessed = '1';
const items = Array.from(ul.querySelectorAll('li'));
if (items.length <= MAX_VISIBLE) return; /* nada a fazer */
/* Extrai preço numérico de cada item */
function getPrice(li) {
const label = li.querySelector('label');
if (!label) return Infinity;
/* Aceita formatos: R$40,24 | R$ 40.24 | 40,24 */
const match = label.textContent.match(/R?\$?\s*([\d.,]+)/);
if (!match) return Infinity;
/* Converte "40,24" → 40.24 e "1.040,24" → 1040.24 */
const raw = match[1].replace(/\.(?=\d{3})/g, '').replace(',', '.');
const val = parseFloat(raw);
return isNaN(val) ? Infinity : val;
}
/* Mantém retirada no local sempre no topo (preço 0 já garante isso) */
const sorted = items.slice().sort(function (a, b) {
return getPrice(a) - getPrice(b);
});
/* Reordena o DOM conforme o sort */
sorted.forEach(function (li) { ul.appendChild(li); });
/* Esconde a partir do índice MAX_VISIBLE */
const hidden = sorted.slice(MAX_VISIBLE);
hidden.forEach(function (li) { li.classList.add('frete-oculto'); });
/* Cria botão de toggle */
const btn = document.createElement('button');
btn.type = 'button';
btn.className = 'frete-toggle-btn';
btn.textContent = LABEL_MAIS;
let expanded = false;
btn.addEventListener('click', function () {
expanded = !expanded;
hidden.forEach(function (li) {
li.classList.toggle('frete-oculto', !expanded);
});
btn.textContent = expanded ? LABEL_MENOS : LABEL_MAIS;
});
ul.parentNode.insertBefore(btn, ul.nextSibling);
});
}
/* ── Observa mudanças no DOM (WooCommerce atualiza frete via AJAX) ── */
const observer = new MutationObserver(function (mutations) {
for (const m of mutations) {
if (m.addedNodes.length || m.removedNodes.length) {
collapseShipping();
}
}
});
function init() {
collapseShipping();
const cart = document.querySelector('.woocommerce-checkout, .woocommerce-cart, form.cart');
if (cart) {
observer.observe(cart, { childList: true, subtree: true });
} else {
/* Fallback: observa o body inteiro */
observer.observe(document.body, { childList: true, subtree: true });
}
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();