(function () {
function init(form) {
if (!form || form.dataset.brxVarImgOnlyInit) return;
form.dataset.brxVarImgOnlyInit = '1';
// Read attribute slugs from form
const colorAttr = (form.getAttribute('data-color-attr') || 'pa_color').replace(/^attribute_/, '');
const sizeAttr = (form.getAttribute('data-size-attr') || 'pa_size').replace(/^attribute_/, '');
// Main image inside this product card/container
const block = form.closest('.brxe-block, .product, .single-product, .brxe-container') || document;
const mainImg = block.querySelector('img.brxe-image');
if (!mainImg) return;
// Save featured/original once
if (!mainImg.dataset.origSrc) {
mainImg.dataset.origSrc = mainImg.getAttribute('src') || '';
mainImg.dataset.origSrcset = mainImg.getAttribute('srcset') || '';
mainImg.dataset.origSizes = mainImg.getAttribute('sizes') || '';
}
// Variation payload from Woo (source of truth for big image)
let variations = [];
try {
const raw = form.getAttribute('data-product_variations');
if (raw) variations = JSON.parse(raw);
} catch (e){}
// Hidden selects (reflect true state)
const colorSelect = form.querySelector('select[name="attribute_' + colorAttr + '"]');
const sizeSelect = form.querySelector('select[name="attribute_' + sizeAttr + '"]');
// UI parts we toggle
const addWrap = form.querySelector('.woocommerce-variation-add-to-cart')
|| form.querySelector('.single_add_to_cart_button')?.closest('form')
|| form.querySelector('.single_add_to_cart_button');
const addBtn = form.querySelector('.single_add_to_cart_button');
const qty = form.querySelector('.quantity');
// Try to find a visible wrapper for the SIZE control
let sizeWrap = form.querySelector('.bricks-variation-swatches[data-attribute_name="attribute_' + sizeAttr + '"]')
|| form.querySelector('.bricks-variation-swatches.bricks-swatch-label');
if (!sizeWrap && sizeSelect) {
sizeWrap = sizeSelect.closest('tr') || sizeSelect.closest('.form-row') || sizeSelect.closest('.value') || sizeSelect.parentElement;
}
// ----------------- helpers -----------------
function applyImageObj(img){
if (!img) return false;
const src = img.full_src || img.src;
if (!src) return false;
mainImg.setAttribute('src', src);
if (img.srcset) mainImg.setAttribute('srcset', img.srcset); else mainImg.removeAttribute('srcset');
if (img.sizes) mainImg.setAttribute('sizes', img.sizes); else mainImg.removeAttribute('sizes');
return true;
}
function restoreFeatured(){
const s = mainImg.dataset.origSrc;
const ss = mainImg.dataset.origSrcset;
const sz = mainImg.dataset.origSizes;
if (s) mainImg.setAttribute('src', s);
if (ss) mainImg.setAttribute('srcset', ss); else mainImg.removeAttribute('srcset');
if (sz) mainImg.setAttribute('sizes', sz); else mainImg.removeAttribute('sizes');
}
function getSelectedColor(){ return colorSelect && colorSelect.value ? colorSelect.value : ''; }
function getSelectedSize(){ return sizeSelect && sizeSelect.value ? sizeSelect.value : ''; }
// Find a matching variation (prefer exact match if size is used; else match by color only)
function findVariation(color, size){
if (!Array.isArray(variations)) return null;
if (size) {
// exact color+size
const exact = variations.find(v =>
v.attributes &&
v.attributes['attribute_' + colorAttr] === color &&
v.attributes['attribute_' + sizeAttr] === size
);
if (exact) return exact;
}
// fallback: first with same color
return variations.find(v => v.attributes && v.attributes['attribute_' + colorAttr] === color) || null;
}
// Always set big image from VARIATION
function setImageFromVariation(color, size){
const v = findVariation(color, size);
if (v && v.image && (v.image.src || v.image.full_src)) {
return applyImageObj(v.image);
}
return false;
}
// Default when nothing selected: first variation with an image; else featured
function setDefaultImage(){
const v = (variations || []).find(v => v.image && (v.image.src || v.image.full_src));
if (v) return applyImageObj(v.image);
restoreFeatured();
return false;
}
// Show/hide Size + Qty + Add button until a color is chosen
function updateVisibility(){
const hasColor = !!getSelectedColor();
if (sizeWrap) sizeWrap.style.display = hasColor ? (sizeWrap.classList.contains('bricks-variation-swatches') ? 'flex' : '') : 'none';
if (qty) qty.style.display = hasColor ? '' : 'none';
if (addWrap) addWrap.style.display = hasColor ? '' : 'none';
if (addBtn) addBtn.style.display = hasColor ? '' : 'none';
}
// ----------------- init -----------------
// If something is preselected, use that variation image; else default
const initColor = getSelectedColor();
const initSize = getSelectedSize();
if (initColor) { setImageFromVariation(initColor, initSize) || setDefaultImage(); }
else { setDefaultImage(); }
updateVisibility();
// ----------------- events -----------------
// Clicks on any swatch list
form.addEventListener('click', function(e){
const onSwatch = e.target.closest('ul.bricks-variation-swatches li');
const onReset = e.target.closest('.reset_variations');
if (onSwatch) {
setTimeout(() => {
setImageFromVariation(getSelectedColor(), getSelectedSize()) || setDefaultImage();
updateVisibility();
}, 0);
}
if (onReset) {
setTimeout(() => { setDefaultImage(); updateVisibility(); }, 0);
}
});
// Changes on hidden selects
if (colorSelect) colorSelect.addEventListener('change', () => {
setImageFromVariation(getSelectedColor(), getSelectedSize()) || setDefaultImage();
updateVisibility();
});
if (sizeSelect) sizeSelect.addEventListener('change', () => {
// If size influences image, re-apply (exact match first)
setImageFromVariation(getSelectedColor(), getSelectedSize()) || setDefaultImage();
});
// Woo events
if (window.jQuery) {
const $ = window.jQuery;
// When Woo finds a variation, use its image
$(form).on('found_variation', function(e, variation){
if (variation && variation.image && (variation.image.src || variation.image.full_src)) {
applyImageObj(variation.image);
}
updateVisibility();
});
// On reset, revert to default (first variation image or featured)
$(form).on('reset_data hide_variation', function(){
setDefaultImage();
updateVisibility();
});
}
}
function boot(){ document.querySelectorAll('form.variations_form, form.cart').forEach(init); }
document.addEventListener('DOMContentLoaded', boot);
// Re-init for AJAX/Bricks inserts
const mo = new MutationObserver(() => {
document.querySelectorAll('form.variations_form:not([data-brx-var-img-only-init]), form.cart:not([data-brx-var-img-only-init])')
.forEach(init);
});
mo.observe(document.documentElement, { childList:true, subtree:true });
})();
/* ✅ Normalize swatch structure */
.bricks-variation-swatches.bricks-swatch-image li,
.bricks-variation-swatches.bricks-swatch-label li {
position: relative;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid #ddd;
border-radius: 0px;
box-sizing: border-box;
cursor: pointer;
transition: all 0.2s ease;
background: #fff;
}
/* ✅ Fix inner anchor without breaking tooltip */
.bricks-variation-swatches li > a {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
border: none !important;
background: transparent !important;
text-decoration: none;
color: inherit;
box-shadow: none;
cursor: inherit;
}
/* ✅ Image swatches */
.bricks-swatch-image li,
.bricks-swatch-image li a {
width: 28px;
height: 28px;
}
.bricks-swatch-image li img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 6px;
}
/* ✅ Size/Label swatches */
.bricks-swatch-label li,
.bricks-swatch-label li a {
min-width: 28px;
height: 28px;
font-size: 12px;
font-weight: 600;
text-transform: uppercase;
border-radius: 8px;
border: 1px solid #ddd;
transition: all 0.2s ease;
background: #fff;
}
/* Hover + Selected states */
.bricks-variation-swatches li:hover {
border-color: #000;
}
.bricks-variation-swatches li.selected,
.bricks-variation-swatches li.bricks-swatch-selected {
border-color: #000;
background: #000;
color: #fff;
}
/* ✅ Keep tooltip visible */
.bricks-variation-swatches li[data-balloon]:hover::after,
.bricks-variation-swatches li[data-balloon]:hover::before {
opacity: 1 !important;
visibility: visible !important;
}
/* Limit color swatches to 5 on mobile */
@media (max-width: 767px) {
.brx-loop-variation-wrapper .bricks-variation-swatches.bricks-swatch-image li:nth-child(n+5) {
display: none !important;
}
}
/*Swatches padding*/
form.cart table.variations td, form.woocommerce-cart-form table.variations td {
padding-top: 5px !important;
padding-bottom: 0px !important;
}
form.cart .quantity+button, form.woocommerce-cart-form .quantity+button {
font-weight: 700 !important;
}
form.cart .quantity + button:hover,
form.woocommerce-cart-form .quantity + button:hover {
background-color: #BECCFF !important; /* brand gold */
color: #000000 !important;
transition: all 0.2s ease;
}