diff --git a/assets/apps/customizer-controls/src/repeater/Repeater.js b/assets/apps/customizer-controls/src/repeater/Repeater.js index 66daf9663a..af0132dfcf 100644 --- a/assets/apps/customizer-controls/src/repeater/Repeater.js +++ b/assets/apps/customizer-controls/src/repeater/Repeater.js @@ -44,7 +44,7 @@ const Repeater = ({ for (const [field] of Object.entries(itemFields)) { newItem.visibility = 'yes'; - if (typeof value[0][field] === 'boolean') { + if (typeof value[0]?.[field] === 'boolean') { newItem[field] = true; if (field === 'hide_on_mobile') { newItem[field] = false; diff --git a/assets/apps/customizer-controls/src/repeater/RepeaterItemContent.js b/assets/apps/customizer-controls/src/repeater/RepeaterItemContent.js index 27d86f559f..0ec169a4fe 100644 --- a/assets/apps/customizer-controls/src/repeater/RepeaterItemContent.js +++ b/assets/apps/customizer-controls/src/repeater/RepeaterItemContent.js @@ -169,7 +169,40 @@ const RepeaterItemContent = ({ /> ); case 'switcher': - return ; + const selectedOption = + value[index][key] || Object.keys(currentField.options)[0]; + + return ( + <> + + {Object.entries(currentField.options).map( + ([optionKey, option]) => { + return ( + + ); + } + )} + + {currentField.options?.[selectedOption]?.fields.map( + (componentId) => { + return toComponent(componentId, value[index]); + } + )} + + ); case 'media': return ( { - const selectedOption = - value[index][fieldId] || Object.keys(currentField.options)[0]; - - return ( - <> - - {Object.entries(currentField.options).map( - ([optionKey, option]) => { - return ( - - ); - } - )} - - {currentField.options?.[selectedOption]?.fields.map( - (componentId) => { - return toComponent(componentId, value[index]); - } - )} - - ); - }; - return (
4) { - handleExclusiveSlider(); - } - - if ( - '1' !== neveShopSlider.isSparkActive && - $body.hasClass('single-product') - ) { - handleGallerySlider(); - } +/** + * Init shop. + */ +function initShop() { + if (document.body.classList.contains('woocommerce')) { + handleShopSidebar(); } - /** - * Add prev and next - * - * @param {Node} targetNode - * @param {Node} slider - * @param {string} vertical - */ - function addNextPrev(targetNode, slider, vertical = false) { - const $next = $('') - .addClass('next dashicons') - .addClass( - 'dashicons-arrow-' + (vertical ? 'down' : 'right') + '-alt2' - ); - const $prev = $('') - .addClass('prev dashicons') - .addClass( - 'dashicons-arrow-' + (vertical ? 'up' : 'left') + '-alt2' - ); - - $prev.on('click', () => slider.goTo('prev')); + const countExclusive = document.querySelectorAll( + '.exclusive-products li.product' + ).length; - $next.on('click', () => slider.goTo('next')); - - const $target = $(targetNode); - $prev.insertBefore($target); - $next.insertAfter($target); + if ( + document.body.classList.contains('nv-exclusive') && + countExclusive > 4 + ) { + handleExclusiveSlider(); } - - /** - * Handle the shop sidebar. - */ - function handleShopSidebar() { - const $sidebar = $('.shop-sidebar'); - if (0 === $sidebar.length) { - return; - } - const $html = $('html'); - const $toggles = $('.nv-sidebar-toggle'); - $toggles.each(function () { - $(this).on('click', function (e) { - e.preventDefault(); - $sidebar.toggleClass('sidebar-open'); - $html.toggleClass('menu-openend'); - }); - }); +} + +/** + * Handle the shop sidebar. + */ +function handleShopSidebar() { + const sidebar = document.querySelector('.shop-sidebar'); + if (sidebar === null) { + return; } - - /** - * Handle Exclusive Products Slider - */ - function handleExclusiveSlider() { - const $items = $('ul.exclusive-products'); - - if (0 === $items.length) return; - - const responsive = { - 0: { items: 2, gutter: 21 }, - 768: { items: 4, gutter: 27 }, - 1200: { items: 4, gutter: 30 }, - }; - - const slider = tns({ - container: 'ul.exclusive-products', - slideBy: 1, - arrowKeys: true, - loop: true, - autoplay: true, - items: 4, - edgePadding: 0, - autoplayButtonOutput: false, - autoplayHoverPause: true, - speed: 1000, - autoplayTimeout: 3000, - autoplayButton: false, - controls: false, - navPosition: 'bottom', - navContainer: '.dots-nav', - navAsThumbnails: true, - responsive, + const html = document.querySelector('html'); + const toggles = document.querySelectorAll('.nv-sidebar-toggle') || []; + toggles.forEach((toggle) => { + toggle.addEventListener('click', function (e) { + e.preventDefault(); + sidebar.classList.toggle('sidebar-open'); + html.classList.toggle('menu-openend'); }); + }); +} + +/** + * Handle Exclusive Products Slider + */ +function handleExclusiveSlider() { + const items = document.querySelector('ul.exclusive-products'); + + if (items === null) return false; + + const responsive = { + 0: { items: 2, gutter: 21 }, + 768: { items: 4, gutter: 27 }, + 1200: { items: 4, gutter: 30 }, + }; + + const slider = tns({ + container: 'ul.exclusive-products', + slideBy: 1, + arrowKeys: true, + loop: true, + autoplay: true, + items: 4, + edgePadding: 0, + autoplayButtonOutput: false, + autoplayHoverPause: true, + speed: 1000, + autoplayTimeout: 3000, + autoplayButton: false, + controls: false, + navPosition: 'bottom', + navContainer: '.dots-nav', + navAsThumbnails: true, + responsive, + }); - // [If Sparks Variation Swatches is enabled and ] Initialize Sparks Variation Swatches for cloned products. - if ($('body').hasClass('sparks-vs-shop-attribute')) { - slider.events.on('transitionEnd', () => { - document.dispatchEvent( - new CustomEvent('sparksVSNeedsInit', { - detail: { container: '.products.exclusive' }, - }) - ); - }); - } - } - - /** - * Handle Gallery Image Slider - */ - function handleGallerySlider() { - const $galleryNav = $('ol.flex-control-nav'); - - if (0 === $galleryNav.length) return; - - const isDesktop = window.innerWidth >= 992; - - const slider = tns({ - container: 'ol.flex-control-nav', - items: 4, - axis: isDesktop ? 'vertical' : 'horizontal', - slideBy: 'page', - rewind: true, - loop: false, - nav: false, - controls: false, - mouseDrag: true, + // [If Sparks Variation Swatches is enabled and ] Initialize Sparks Variation Swatches for cloned products. + if (document.body.classList.contains('sparks-vs-shop-attribute')) { + slider.events.on('transitionEnd', () => { + document.dispatchEvent( + new CustomEvent('sparksVSNeedsInit', { + detail: { + container: '.products.exclusive', + }, + }) + ); }); - - addNextPrev( - $('.woocommerce-product-gallery .tns-inner')[0], - slider, - isDesktop - ); } +} - /** - * Run JS on load. - */ - $(function () { - initShop(); - }); -})(jQuery); +/** + * Run JS on load. + */ +window.addEventListener('load', initShop); diff --git a/assets/scss/components/compat/woocommerce/_sidebar.scss b/assets/scss/components/compat/woocommerce/_sidebar.scss index da52a01c80..4249c25ce4 100644 --- a/assets/scss/components/compat/woocommerce/_sidebar.scss +++ b/assets/scss/components/compat/woocommerce/_sidebar.scss @@ -56,95 +56,3 @@ } } } - -body:not(.nv-left-gallery):not(.sp-slider-gallery):not([class*="related-products-columns-"]) { - - .tns-ovh { - display: flex; - align-items: center; - cursor: pointer; - } - - .tns-inner { - overflow: hidden; - } - - .tns-visually-hidden { - display: none; - } - - /* Make WooCommerce gallery vertical on desktop */ - @media (min-width: 992px) { - - div.product { - - .onsale { - left: 110px; - } - - div.images { - display: flex; - flex-direction: row-reverse; - gap: 10px; - - .tns-ovh { - width: 100px; - flex-direction: column; - position: relative; - - .dashicons { - position: absolute; - z-index: 1; - color: var(--nv-text-color); - width: 100px; - text-align: center; - - &.prev { - top: 0; - } - - &.next { - bottom: 0; - } - - &:hover { - background-color: var(--nv-site-bg); - } - } - } - - .flex-viewport { - width: calc(100% - 100px); - } - - .flex-control-nav { - display: flex; - flex-direction: column; - width: 100px; - margin-top: -5px; - - li { - width: 100px; - } - } - } - } - } - - /* On mobile, keep horizontal layout */ - @media (max-width: 991px) { - - div.product { - - div.images { - - .flex-control-nav { - flex-direction: row; - width: auto; - max-height: none; - display: flex; - } - } - } - } -} diff --git a/globals/sanitize-functions.php b/globals/sanitize-functions.php index 73775a78d4..47fe9d1489 100644 --- a/globals/sanitize-functions.php +++ b/globals/sanitize-functions.php @@ -346,6 +346,7 @@ function neve_sanitize_meta_repeater( $value ) { 'field', 'format', 'fallback', + '__kbKey', ]; if ( empty( $value ) ) { diff --git a/inc/core/front_end.php b/inc/core/front_end.php index 05232dc1d2..3b8475f923 100644 --- a/inc/core/front_end.php +++ b/inc/core/front_end.php @@ -465,16 +465,9 @@ private function add_scripts() { } if ( class_exists( 'WooCommerce', false ) && is_woocommerce() ) { - wp_register_script( 'neve-shop-script', NEVE_ASSETS_URL . 'js/build/modern/shop.js', array( 'jquery', 'wc-single-product' ), NEVE_VERSION, true ); + wp_register_script( 'neve-shop-script', NEVE_ASSETS_URL . 'js/build/modern/shop.js', array(), NEVE_VERSION, true ); wp_enqueue_script( 'neve-shop-script' ); wp_script_add_data( 'neve-shop-script', 'async', true ); - wp_localize_script( - 'neve-shop-script', - 'neveShopSlider', - array( - 'isSparkActive' => is_plugin_active( 'sparks-for-woocommerce/sparks-for-woocommerce.php' ), - ) - ); } if ( $this->should_load_comments_reply() ) {