Changeset 357926
- Timestamp:
- 11/08/2026 12:45:09 AM (less than one hour ago)
- Location:
- codersly-shop/1.2.8
- Files:
-
- 1 added
- 23 edited
- 1 copied
-
. (copied) (copied from codersly-shop/1.2.7 )
-
CHANGELOG.txt (modified) (1 diff)
-
assets/css/header.css (modified) (4 diffs)
-
assets/css/header.min.css (modified) (4 diffs)
-
assets/js/customizer.js (modified) (2 diffs)
-
assets/js/header.js (modified) (3 diffs)
-
assets/js/header.min.js (modified) (3 diffs)
-
assets/js/main.js (modified) (1 diff)
-
functions.php (modified) (2 diffs)
-
inc/assets.php (modified) (1 diff)
-
inc/class-codersly-shop-header-manager.php (modified) (1 diff)
-
inc/customizer/options-header.php (modified) (4 diffs)
-
inc/customizer/options-logo.php (added)
-
inc/hooks.php (modified) (1 diff)
-
inc/setup.php (modified) (1 diff)
-
inc/template-functions.php (modified) (3 diffs)
-
languages/codersly-shop.pot (modified) (1 diff)
-
readme.txt (modified) (2 diffs)
-
style.css (modified) (1 diff)
-
template-parts/headers/components/logo.php (modified) (3 diffs)
-
template-parts/headers/header-1.php (modified) (2 diffs)
-
template-parts/headers/header-2.php (modified) (2 diffs)
-
template-parts/headers/header-3.php (modified) (2 diffs)
-
template-parts/headers/header-4.php (modified) (1 diff)
-
template-parts/headers/header-5.php (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
codersly-shop/1.2.8/CHANGELOG.txt
r356755 r357926 1 v1.2.8 — Desktop logo label clarification (same version) 2 - The existing add-on Logo Max Height (px) control is now displayed as Desktop Logo Size (px). 3 - No duplicate control or settings migration: the saved value and sizing behavior are unchanged. 4 5 v1.2.8 — Single shared logo, duplicate control cleanup (same version) 6 - Site Identity now exposes one Site Logo image for desktop and mobile. 7 - Removed the redundant, nonfunctional Desktop Logo Size control and the separate Mobile Logo image control. 8 - Existing licensed add-on Logo Max Height (px) remains the desktop height setting (no stored value changed). 9 - Mobile Logo Max Height (px) remains available for independent mobile sizing; previous mobile height value is preserved. 10 - Single-logo HTML replaces the device-image swap, keeping other 1.2.8 improvements intact. 11 12 v1.2.8 — Device-specific Site Identity logo options (same version) 13 - Site Identity: existing custom logo renamed Desktop Logo, without changing its stored value. 14 - Optional Mobile Logo image; mobile inherits desktop logo when no separate image is chosen. 15 - Separate Desktop Logo Size (40px default) and Mobile Logo Size (30px default), each 16–200px. 16 - Responsive image selection covers all header variants; footer/logo elsewhere remains unchanged. 17 - All previous sticky-header, mobile drawer, submenu and branding fixes preserved. 18 19 ## 1.2.8 20 - Separated desktop and mobile sticky-header Customizer controls; existing desktop preference is preserved, new mobile setting defaults off. 21 - Enabled mobile-only sticky positioning for all five header layouts without moving mobile search, Cart, Hamburger or drawer. 22 - Fixed excess spacing between the mobile header logo and site title: now centered together as a compact 8px-gap group, without moving the cart or menu controls. 23 - Refined mobile branding alignment within the space before the unchanged cart and hamburger controls. 24 - Widened the mobile menu drawer and wrapped long contact text to prevent clipping. 25 - Enabled all levels of mobile menu submenus across every header variant, with accessible expand/collapse buttons. 26 - Increased the mobile header left padding from 8px to 18px to provide comfortable spacing for the logo and site title. 27 - Updated theme version metadata and bundled CSS files to 1.2.8. 28 1 29 ## 1.2.7 2 30 - Maintenance: moved Show Logo, Show Site Title, Show Tagline and Logo Max Height controls into the licensed companion add-on; the free theme now uses standard branding defaults. -
codersly-shop/1.2.8/assets/css/header.css
r346202 r357926 71 71 } 72 72 73 /* Default logo size (desktop-friendly) */ 74 .bt-logo__img { max-height: 48px; } 73 /* One uploaded site logo is used at all viewport widths. */ 74 /* Set a desktop cap on both header variants, overriding style.css's 40px. */ 75 .bt-header .bt-logo__img, .bt-header .site-logo, .bt-header .custom-logo-link img { max-height: var(--bt-logo-h, 40px); width: auto; } 75 76 76 77 /* -------------------- Primary Menu -------------------- */ … … 531 532 /* Reserve the right side for Cart + Hamburger. */ 532 533 .bt-header-inner{ 533 padding: .35rem 8px !important;534 padding: .35rem 8px .35rem 18px !important; 534 535 gap: 8px; 535 536 position: relative; … … 552 553 /* Smaller logo on mobile */ 553 554 .bt-header .custom-logo-link img, 554 .bt-logo__img{ 555 max-height: 30px !important; 555 .bt-header .bt-logo__img, 556 .bt-header .site-logo { 557 max-height: var(--bt-logo-h-mobile, 30px) !important; 556 558 width: auto; 557 559 } … … 853 855 } 854 856 } 857 858 859 /* ========================================================= 860 v1.2.8 mobile refinement — centered branding, wider drawer, 861 accessible nested navigation. Desktop layout is unchanged. 862 ========================================================= */ 863 @media (max-width: 768px) { 864 /* Reserve the right-hand controls' existing positions: cart at 58px, 865 hamburger at 8px. Center only within the space to their left. */ 866 .bt-header .bt-header-inner { 867 padding: .35rem 114px .35rem 16px !important; 868 justify-content: flex-start !important; 869 } 870 /* Treat the logo and site title as ONE tightly spaced branding group. 871 Previously auto margins on .site-branding separated them widely. */ 872 .bt-header .bt-header-left { 873 flex: 1 1 100% !important; 874 min-width: 0; 875 gap: 8px !important; 876 padding-right: 0 !important; 877 justify-content: center !important; 878 } 879 .bt-header .bt-header-left .site-branding { 880 flex: 0 0 auto; 881 width: auto; 882 max-width: 100%; 883 min-width: 0; 884 margin: 0 !important; 885 justify-content: center !important; 886 } 887 .bt-header .bt-header-left .bt-site-title { 888 flex: 0 1 auto; 889 min-width: 0; 890 margin: 0 !important; 891 } 892 .bt-header .bt-header-left .bt-brand-title, 893 .bt-header .bt-header-left .site-title { 894 min-width: 0; 895 } 896 897 /* 50vw clipped email/contact text; 68vw makes the drawer more usable. */ 898 .bt-drawer { 899 width: 68vw; 900 max-width: 380px; 901 box-sizing: border-box; 902 } 903 .bt-drawer-inner, 904 .bt-drawer-scroll, 905 .bt-drawer-footer { 906 box-sizing: border-box; 907 min-width: 0; 908 } 909 .bt-drawer-footer, 910 .bt-drawer-footer * { 911 overflow-wrap: anywhere; 912 word-break: normal; 913 } 914 .bt-drawer .bt-drawer-menu a { 915 overflow-wrap: anywhere; 916 } 917 918 /* Separate arrow button: tapping it expands the submenu without 919 preventing navigation when the parent label has a real URL. */ 920 .bt-drawer .bt-drawer-menu li.menu-item-has-children > a { 921 padding-right: 44px; 922 } 923 .bt-drawer .bt-drawer-menu li.menu-item-has-children > a::after { 924 content: none; 925 } 926 .bt-drawer .bt-drawer-menu .bt-submenu-toggle { 927 position: absolute; 928 z-index: 1; 929 right: 0; 930 top: 0; 931 display: flex; 932 align-items: center; 933 justify-content: center; 934 width: 40px; 935 min-height: 42px; 936 padding: 0; 937 border: 0; 938 border-radius: 6px; 939 background: transparent; 940 color: var(--bt-fg); 941 cursor: pointer; 942 } 943 .bt-drawer .bt-drawer-menu .bt-submenu-toggle::after { 944 content: ''; 945 display: block; 946 width: 8px; 947 height: 8px; 948 border-right: 2px solid currentColor; 949 border-bottom: 2px solid currentColor; 950 transform: translateY(-2px) rotate(45deg); 951 transition: transform .15s ease; 952 } 953 .bt-drawer .bt-drawer-menu .bt-submenu-toggle[aria-expanded='true']::after { 954 transform: translateY(2px) rotate(225deg); 955 } 956 .bt-drawer .bt-drawer-menu .bt-submenu-toggle:hover, 957 .bt-drawer .bt-drawer-menu .bt-submenu-toggle:focus-visible { 958 background: var(--bt-soft); 959 } 960 .bt-drawer .bt-drawer-menu .bt-submenu-toggle:focus-visible { 961 outline: 2px solid var(--bt-accent); 962 outline-offset: 2px; 963 } 964 } 965 966 @media (max-width: 360px) { 967 .bt-header .bt-header-left .site-title { 968 font-size: 16px !important; 969 } 970 } 971 972 /* ========================================================= 973 v1.2.8 — independently controlled MOBILE sticky header. 974 The existing .bt-header--sticky setting remains desktop-only; 975 mobile uses .bt-header--sticky-mobile, including header variants 2–5. 976 Keep the separate search row in normal document flow and leave the 977 fixed drawer/Cart/Hamburger positioning unchanged. 978 ========================================================= */ 979 @media (max-width: 768px) { 980 .bt-header.bt-header--sticky-mobile { 981 position: -webkit-sticky !important; 982 position: sticky !important; 983 top: 0 !important; 984 z-index: 1001; 985 background: var(--bt-bg, #fff); 986 border-bottom: 1px solid var(--bt-b, #e5e7eb); 987 box-shadow: 0 2px 6px rgba(0, 0, 0, .06) !important; 988 } 989 .bt-header.bt-header--sticky-mobile.bt-header-scrolled { 990 box-shadow: 0 6px 20px rgba(0, 0, 0, .10) !important; 991 } 992 } -
codersly-shop/1.2.8/assets/css/header.min.css
r346202 r357926 71 71 } 72 72 73 /* Default logo size (desktop-friendly) */ 74 .bt-logo__img { max-height: 48px; } 73 /* One uploaded site logo is used at all viewport widths. */ 74 /* Set a desktop cap on both header variants, overriding style.css's 40px. */ 75 .bt-header .bt-logo__img, .bt-header .site-logo, .bt-header .custom-logo-link img { max-height: var(--bt-logo-h, 40px); width: auto; } 75 76 76 77 /* -------------------- Primary Menu -------------------- */ … … 531 532 /* Reserve the right side for Cart + Hamburger. */ 532 533 .bt-header-inner{ 533 padding: .35rem 8px !important;534 padding: .35rem 8px .35rem 18px !important; 534 535 gap: 8px; 535 536 position: relative; … … 552 553 /* Smaller logo on mobile */ 553 554 .bt-header .custom-logo-link img, 554 .bt-logo__img{ 555 max-height: 30px !important; 555 .bt-header .bt-logo__img, 556 .bt-header .site-logo { 557 max-height: var(--bt-logo-h-mobile, 30px) !important; 556 558 width: auto; 557 559 } … … 853 855 } 854 856 } 857 858 859 /* ========================================================= 860 v1.2.8 mobile refinement — centered branding, wider drawer, 861 accessible nested navigation. Desktop layout is unchanged. 862 ========================================================= */ 863 @media (max-width: 768px) { 864 /* Reserve the right-hand controls' existing positions: cart at 58px, 865 hamburger at 8px. Center only within the space to their left. */ 866 .bt-header .bt-header-inner { 867 padding: .35rem 114px .35rem 16px !important; 868 justify-content: flex-start !important; 869 } 870 /* Treat the logo and site title as ONE tightly spaced branding group. 871 Previously auto margins on .site-branding separated them widely. */ 872 .bt-header .bt-header-left { 873 flex: 1 1 100% !important; 874 min-width: 0; 875 gap: 8px !important; 876 padding-right: 0 !important; 877 justify-content: center !important; 878 } 879 .bt-header .bt-header-left .site-branding { 880 flex: 0 0 auto; 881 width: auto; 882 max-width: 100%; 883 min-width: 0; 884 margin: 0 !important; 885 justify-content: center !important; 886 } 887 .bt-header .bt-header-left .bt-site-title { 888 flex: 0 1 auto; 889 min-width: 0; 890 margin: 0 !important; 891 } 892 .bt-header .bt-header-left .bt-brand-title, 893 .bt-header .bt-header-left .site-title { 894 min-width: 0; 895 } 896 897 /* 50vw clipped email/contact text; 68vw makes the drawer more usable. */ 898 .bt-drawer { 899 width: 68vw; 900 max-width: 380px; 901 box-sizing: border-box; 902 } 903 .bt-drawer-inner, 904 .bt-drawer-scroll, 905 .bt-drawer-footer { 906 box-sizing: border-box; 907 min-width: 0; 908 } 909 .bt-drawer-footer, 910 .bt-drawer-footer * { 911 overflow-wrap: anywhere; 912 word-break: normal; 913 } 914 .bt-drawer .bt-drawer-menu a { 915 overflow-wrap: anywhere; 916 } 917 918 /* Separate arrow button: tapping it expands the submenu without 919 preventing navigation when the parent label has a real URL. */ 920 .bt-drawer .bt-drawer-menu li.menu-item-has-children > a { 921 padding-right: 44px; 922 } 923 .bt-drawer .bt-drawer-menu li.menu-item-has-children > a::after { 924 content: none; 925 } 926 .bt-drawer .bt-drawer-menu .bt-submenu-toggle { 927 position: absolute; 928 z-index: 1; 929 right: 0; 930 top: 0; 931 display: flex; 932 align-items: center; 933 justify-content: center; 934 width: 40px; 935 min-height: 42px; 936 padding: 0; 937 border: 0; 938 border-radius: 6px; 939 background: transparent; 940 color: var(--bt-fg); 941 cursor: pointer; 942 } 943 .bt-drawer .bt-drawer-menu .bt-submenu-toggle::after { 944 content: ''; 945 display: block; 946 width: 8px; 947 height: 8px; 948 border-right: 2px solid currentColor; 949 border-bottom: 2px solid currentColor; 950 transform: translateY(-2px) rotate(45deg); 951 transition: transform .15s ease; 952 } 953 .bt-drawer .bt-drawer-menu .bt-submenu-toggle[aria-expanded='true']::after { 954 transform: translateY(2px) rotate(225deg); 955 } 956 .bt-drawer .bt-drawer-menu .bt-submenu-toggle:hover, 957 .bt-drawer .bt-drawer-menu .bt-submenu-toggle:focus-visible { 958 background: var(--bt-soft); 959 } 960 .bt-drawer .bt-drawer-menu .bt-submenu-toggle:focus-visible { 961 outline: 2px solid var(--bt-accent); 962 outline-offset: 2px; 963 } 964 } 965 966 @media (max-width: 360px) { 967 .bt-header .bt-header-left .site-title { 968 font-size: 16px !important; 969 } 970 } 971 972 /* ========================================================= 973 v1.2.8 — independently controlled MOBILE sticky header. 974 The existing .bt-header--sticky setting remains desktop-only; 975 mobile uses .bt-header--sticky-mobile, including header variants 2–5. 976 Keep the separate search row in normal document flow and leave the 977 fixed drawer/Cart/Hamburger positioning unchanged. 978 ========================================================= */ 979 @media (max-width: 768px) { 980 .bt-header.bt-header--sticky-mobile { 981 position: -webkit-sticky !important; 982 position: sticky !important; 983 top: 0 !important; 984 z-index: 1001; 985 background: var(--bt-bg, #fff); 986 border-bottom: 1px solid var(--bt-b, #e5e7eb); 987 box-shadow: 0 2px 6px rgba(0, 0, 0, .06) !important; 988 } 989 .bt-header.bt-header--sticky-mobile.bt-header-scrolled { 990 box-shadow: 0 6px 20px rgba(0, 0, 0, .10) !important; 991 } 992 } -
codersly-shop/1.2.8/assets/js/customizer.js
r356755 r357926 7 7 if (!api) return; 8 8 9 if (api('codersly_shop_header_sticky')) { 10 api('codersly_shop_header_sticky', (value) => { 9 // Keep the saved desktop setting and the new mobile setting independent. 10 const stickySettings = { 11 codersly_shop_header_sticky: 'bt-header--sticky', 12 codersly_shop_header_sticky_mobile: 'bt-header--sticky-mobile' 13 }; 14 Object.entries(stickySettings).forEach(([settingId, className]) => { 15 if (!api(settingId)) return; 16 api(settingId, (value) => { 11 17 const apply = (enabled) => { 12 d.querySelectorAll('#masthead, .bt-header').forEach((header) => { 13 header.classList.toggle('bt-header--sticky', !!enabled); 18 const isEnabled = enabled === true || enabled === 1 || enabled === '1'; 19 d.querySelectorAll('.bt-header').forEach((header) => { 20 header.classList.toggle(className, isEnabled); 21 const activeClass = window.matchMedia('(max-width: 768px)').matches 22 ? 'bt-header--sticky-mobile' : 'bt-header--sticky'; 23 header.classList.toggle('bt-header-scrolled', 24 header.classList.contains(activeClass) && window.scrollY > 10); 14 25 }); 15 26 }; … … 17 28 value.bind(apply); 18 29 }); 19 } 30 }); 20 31 21 32 const componentMap = { -
codersly-shop/1.2.8/assets/js/header.js
r345366 r357926 132 132 }); 133 133 134 // Drawer accordion logic (NO auto-close on other parents) 135 // - Parent items with children: toggle .is-open and aria-expanded 136 // - Leaf links (no children): navigate and close drawer 134 // Build accessible, independent dropdown controls for every nested drawer item. 135 // Parent links remain links; their arrow buttons expand/collapse submenus. 136 qsa('.bt-drawer-menu li', drawerInner || document).forEach((item, index) => { 137 const submenu = Array.from(item.children).find((child) => 138 child.matches('ul.sub-menu, ul.children') 139 ); 140 if (!submenu) return; 141 142 const link = Array.from(item.children).find((child) => child.matches('a')); 143 if (!link) return; 144 145 item.classList.add('menu-item-has-children'); 146 const submenuId = submenu.id || `bt-drawer-submenu-${index + 1}`; 147 submenu.id = submenuId; 148 149 const toggle = document.createElement('button'); 150 toggle.type = 'button'; 151 toggle.className = 'bt-submenu-toggle'; 152 toggle.setAttribute('aria-expanded', 'false'); 153 toggle.setAttribute('aria-controls', submenuId); 154 toggle.setAttribute('aria-label', `Expand submenu: ${link.textContent.trim()}`); 155 toggle.dataset.menuName = link.textContent.trim(); 156 link.insertAdjacentElement('afterend', toggle); 157 }); 158 137 159 drawerInner?.addEventListener('click', (e) => { 138 const link = e.target.closest('a'); 139 const li = e.target.closest('li.menu-item'); 140 if (!link || !li) return; 141 142 const hasChildren = li.classList.contains('menu-item-has-children'); 143 if (hasChildren) { 144 e.preventDefault(); 145 li.classList.toggle('is-open'); 146 link.setAttribute( 147 'aria-expanded', 148 li.classList.contains('is-open') ? 'true' : 'false' 160 const toggle = e.target.closest('.bt-submenu-toggle'); 161 if (toggle && drawerInner.contains(toggle)) { 162 e.preventDefault(); 163 const item = toggle.closest('li.menu-item-has-children'); 164 if (!item) return; 165 const open = item.classList.toggle('is-open'); 166 toggle.setAttribute('aria-expanded', String(open)); 167 toggle.setAttribute('aria-label', 168 `${open ? 'Collapse' : 'Expand'} submenu: ${toggle.dataset.menuName}`); 169 return; 170 } 171 172 const link = e.target.closest('.bt-drawer-menu a'); 173 if (!link || !drawerInner.contains(link)) return; 174 const item = link.parentElement?.matches('li.menu-item-has-children') 175 ? link.parentElement : null; 176 const href = (link.getAttribute('href') || '').trim(); 177 // A placeholder parent URL opens the submenu; real parent URLs still work. 178 if (item && (!href || href === '#')) { 179 const arrow = Array.from(item.children).find((child) => 180 child.matches('button.bt-submenu-toggle') 149 181 ); 150 return; 151 } 152 153 // Leaf item: allow navigation, then close drawer 154 const href = link.getAttribute('href') || ''; 182 if (arrow) { 183 e.preventDefault(); 184 arrow.click(); 185 return; 186 } 187 } 188 189 // Real destination links navigate normally. Close on in-page anchors too. 155 190 if (href.startsWith('#')) { 156 191 setTimeout(closeDrawer, 0); … … 172 207 173 208 // Focus trap inside drawer 174 const focusables = qsa(FOCUSABLE, drawer) ;209 const focusables = qsa(FOCUSABLE, drawer).filter((el) => el.getClientRects().length > 0); 175 210 if (!focusables.length) return; 176 211 const first = focusables[0]; … … 205 240 } 206 241 207 /* -------- Sticky Shadow -------- */ 208 if (header?.classList.contains('bt-header--sticky')) { 209 const applyShadow = () => 210 header.classList.toggle('bt-header-scrolled', window.scrollY > 10); 242 /* -------- Responsive Sticky Shadow -------- */ 243 if (header) { 244 const applyShadow = () => { 245 const stickyClass = isDesktop() 246 ? 'bt-header--sticky' : 'bt-header--sticky-mobile'; 247 header.classList.toggle('bt-header-scrolled', 248 header.classList.contains(stickyClass) && window.scrollY > 10); 249 }; 211 250 applyShadow(); 212 251 on('scroll', applyShadow, window); 252 on('resize', applyShadow, window); 213 253 } 214 254 -
codersly-shop/1.2.8/assets/js/header.min.js
r345366 r357926 132 132 }); 133 133 134 // Drawer accordion logic (NO auto-close on other parents) 135 // - Parent items with children: toggle .is-open and aria-expanded 136 // - Leaf links (no children): navigate and close drawer 134 // Build accessible, independent dropdown controls for every nested drawer item. 135 // Parent links remain links; their arrow buttons expand/collapse submenus. 136 qsa('.bt-drawer-menu li', drawerInner || document).forEach((item, index) => { 137 const submenu = Array.from(item.children).find((child) => 138 child.matches('ul.sub-menu, ul.children') 139 ); 140 if (!submenu) return; 141 142 const link = Array.from(item.children).find((child) => child.matches('a')); 143 if (!link) return; 144 145 item.classList.add('menu-item-has-children'); 146 const submenuId = submenu.id || `bt-drawer-submenu-${index + 1}`; 147 submenu.id = submenuId; 148 149 const toggle = document.createElement('button'); 150 toggle.type = 'button'; 151 toggle.className = 'bt-submenu-toggle'; 152 toggle.setAttribute('aria-expanded', 'false'); 153 toggle.setAttribute('aria-controls', submenuId); 154 toggle.setAttribute('aria-label', `Expand submenu: ${link.textContent.trim()}`); 155 toggle.dataset.menuName = link.textContent.trim(); 156 link.insertAdjacentElement('afterend', toggle); 157 }); 158 137 159 drawerInner?.addEventListener('click', (e) => { 138 const link = e.target.closest('a'); 139 const li = e.target.closest('li.menu-item'); 140 if (!link || !li) return; 141 142 const hasChildren = li.classList.contains('menu-item-has-children'); 143 if (hasChildren) { 144 e.preventDefault(); 145 li.classList.toggle('is-open'); 146 link.setAttribute( 147 'aria-expanded', 148 li.classList.contains('is-open') ? 'true' : 'false' 160 const toggle = e.target.closest('.bt-submenu-toggle'); 161 if (toggle && drawerInner.contains(toggle)) { 162 e.preventDefault(); 163 const item = toggle.closest('li.menu-item-has-children'); 164 if (!item) return; 165 const open = item.classList.toggle('is-open'); 166 toggle.setAttribute('aria-expanded', String(open)); 167 toggle.setAttribute('aria-label', 168 `${open ? 'Collapse' : 'Expand'} submenu: ${toggle.dataset.menuName}`); 169 return; 170 } 171 172 const link = e.target.closest('.bt-drawer-menu a'); 173 if (!link || !drawerInner.contains(link)) return; 174 const item = link.parentElement?.matches('li.menu-item-has-children') 175 ? link.parentElement : null; 176 const href = (link.getAttribute('href') || '').trim(); 177 // A placeholder parent URL opens the submenu; real parent URLs still work. 178 if (item && (!href || href === '#')) { 179 const arrow = Array.from(item.children).find((child) => 180 child.matches('button.bt-submenu-toggle') 149 181 ); 150 return; 151 } 152 153 // Leaf item: allow navigation, then close drawer 154 const href = link.getAttribute('href') || ''; 182 if (arrow) { 183 e.preventDefault(); 184 arrow.click(); 185 return; 186 } 187 } 188 189 // Real destination links navigate normally. Close on in-page anchors too. 155 190 if (href.startsWith('#')) { 156 191 setTimeout(closeDrawer, 0); … … 172 207 173 208 // Focus trap inside drawer 174 const focusables = qsa(FOCUSABLE, drawer) ;209 const focusables = qsa(FOCUSABLE, drawer).filter((el) => el.getClientRects().length > 0); 175 210 if (!focusables.length) return; 176 211 const first = focusables[0]; … … 205 240 } 206 241 207 /* -------- Sticky Shadow -------- */ 208 if (header?.classList.contains('bt-header--sticky')) { 209 const applyShadow = () => 210 header.classList.toggle('bt-header-scrolled', window.scrollY > 10); 242 /* -------- Responsive Sticky Shadow -------- */ 243 if (header) { 244 const applyShadow = () => { 245 const stickyClass = isDesktop() 246 ? 'bt-header--sticky' : 'bt-header--sticky-mobile'; 247 header.classList.toggle('bt-header-scrolled', 248 header.classList.contains(stickyClass) && window.scrollY > 10); 249 }; 211 250 applyShadow(); 212 251 on('scroll', applyShadow, window); 252 on('resize', applyShadow, window); 213 253 } 214 254 -
codersly-shop/1.2.8/assets/js/main.js
r330331 r357926 56 56 /* ---------------- Sticky Header Shadow ---------------- */ 57 57 const header = qs('.bt-header'); 58 if (header && header.classList.contains('bt-header--sticky')) { 59 const onScroll = () => 60 header.classList.toggle('bt-header-scrolled', window.scrollY > 10); 58 if (header) { 59 const onScroll = () => { 60 const active = (window.innerWidth <= 768) 61 ? header.classList.contains('bt-header--sticky-mobile') 62 : header.classList.contains('bt-header--sticky'); 63 header.classList.toggle('bt-header-scrolled', active && window.scrollY > 10); 64 }; 61 65 on('scroll', onScroll, window); 66 on('resize', onScroll, window); 62 67 onScroll(); 63 68 } -
codersly-shop/1.2.8/functions.php
r356755 r357926 20 20 */ 21 21 if ( ! defined( 'CODERSLY_SHOP_VERSION' ) ) { 22 define( 'CODERSLY_SHOP_VERSION', '1.2. 7' );22 define( 'CODERSLY_SHOP_VERSION', '1.2.8' ); 23 23 } 24 24 … … 212 212 'inc/customizer/colors.php', 213 213 'inc/customizer/customizer.php', 214 'inc/customizer/options-logo.php', 214 215 'inc/customizer/sanitize.php', 215 216 'inc/customizer/options-header.php', -
codersly-shop/1.2.8/inc/assets.php
r356332 r357926 19 19 function codersly_shop_file_version( $relative_path ) { 20 20 $path = trailingslashit( get_template_directory() ) . ltrim( $relative_path, '/' ); 21 return file_exists( $path ) ? (string) filemtime( $path ) : '1. 1.4';21 return file_exists( $path ) ? (string) filemtime( $path ) : '1.2.8'; 22 22 } 23 23 } -
codersly-shop/1.2.8/inc/class-codersly-shop-header-manager.php
r356755 r357926 199 199 case 'logo': 200 200 return ( codersly_shop_branding_show_logo() 201 && function_exists( 'has_custom_logo' ) && has_custom_logo() )201 && codersly_shop_has_header_logo() ) 202 202 || ( (bool) get_theme_mod( 'codersly_show_site_icon', false ) 203 203 && function_exists( 'has_site_icon' ) && has_site_icon() ); -
codersly-shop/1.2.8/inc/customizer/options-header.php
r320649 r357926 5 5 * 6 6 * - Header variant select (1–5) — Free unlocks only 1; Pro unlocks 2–5 7 * - Sticky header toggle7 * - Independent desktop and mobile sticky header toggles 8 8 * - Component toggles (Search, Account, Cart) 9 9 * - Live-preview for common toggles … … 120 120 121 121 /** 122 * Sticky Header122 * Independent Sticky Header controls 123 123 */ 124 124 $wp_customize->add_setting( … … 134 134 'codersly_shop_header_sticky', 135 135 array( 136 'label' => __( 'Enable Sticky Header', 'codersly-shop' ), 137 'description' => __( 'Make the header stick to the top while scrolling.', 'codersly-shop' ), 136 'label' => __( 'Enable Sticky Header (Desktop)', 'codersly-shop' ), 137 'description' => __( 'Keep the desktop header visible while scrolling. Does not affect mobile.', 'codersly-shop' ), 138 'section' => 'codersly_shop_section_header', 139 'type' => 'checkbox', 140 ) 141 ); 142 143 /** 144 * Mobile sticky: separate from the existing desktop setting. 145 * Off by default so upgrading does not silently change mobile behavior. 146 */ 147 $wp_customize->add_setting( 148 'codersly_shop_header_sticky_mobile', 149 array( 150 'default' => false, 151 'sanitize_callback' => 'codersly_shop_customize_sanitize_checkbox', 152 'transport' => 'postMessage', 153 ) 154 ); 155 156 $wp_customize->add_control( 157 'codersly_shop_header_sticky_mobile', 158 array( 159 'label' => __( 'Enable Sticky Header (Mobile)', 'codersly-shop' ), 160 'description' => __( 'Keep the mobile header visible while scrolling. Desktop setting is independent.', 'codersly-shop' ), 138 161 'section' => 'codersly_shop_section_header', 139 162 'type' => 'checkbox', … … 191 214 'codersly_shop_header_show_cart', 192 215 'codersly_shop_header_sticky', 216 'codersly_shop_header_sticky_mobile', 193 217 'codersly_shop_header_variant', 194 218 ), -
codersly-shop/1.2.8/inc/hooks.php
r356755 r357926 304 304 $show_tagline = codersly_shop_should_show_tagline(); 305 305 $logo_h = codersly_shop_logo_max_height(); 306 307 $css = ':root{--bt-logo-h:' . esc_attr( $logo_h ) . 'px;}'; 306 $logo_mobile_h = codersly_shop_mobile_logo_max_height(); 307 308 $css = ':root{--bt-logo-h:' . esc_attr( $logo_h ) . 'px;--bt-logo-h-mobile:' . esc_attr( $logo_mobile_h ) . 'px;}'; 308 309 if ( ! $show_title ) { 309 310 $css .= '.site-title,.bt-text-logo{display:none!important;}'; -
codersly-shop/1.2.8/inc/setup.php
r356755 r357926 60 60 if ( file_exists( $path ) ) { 61 61 $theme = wp_get_theme(); 62 $ver = $theme->get( 'Version' ) ? $theme->get( 'Version' ) : '1.2. 7';62 $ver = $theme->get( 'Version' ) ? $theme->get( 'Version' ) : '1.2.8'; 63 63 64 64 wp_register_style( $handle, $uri, array(), $ver ); -
codersly-shop/1.2.8/inc/template-functions.php
r356755 r357926 28 28 } 29 29 30 /** Maximum mobile header-logo height in pixels. */ 31 function codersly_shop_mobile_logo_max_height() { 32 $height = (int) get_theme_mod( 'codersly_shop_logo_height_mobile', 30 ); 33 return max( 16, min( 200, $height ) ); 34 } 35 36 /** Whether the shared WordPress Site Identity logo is configured. */ 37 function codersly_shop_has_header_logo() { 38 return (bool) absint( get_theme_mod( 'custom_logo' ) ); 39 } 40 41 /** 42 * Return the single WordPress Site Identity logo used on all devices. 43 * Desktop height comes from the existing premium Logo Max Height setting, 44 * while mobile height is handled via responsive CSS. 45 * 46 * @param string $class CSS class of the logo image. 47 * @return string Safe WordPress attachment-image markup. 48 */ 49 function codersly_shop_header_logo_images( $class = 'site-logo' ) { 50 $logo_id = absint( get_theme_mod( 'custom_logo' ) ); 51 if ( ! $logo_id ) { 52 return ''; 53 } 54 55 $logo_h = codersly_shop_logo_max_height(); 56 $attrs = array( 57 'class' => $class, 58 'style' => 'max-height:' . $logo_h . 'px;height:auto;width:auto;', 59 'loading' => 'eager', 60 'decoding' => 'async', 61 ); 62 63 return wp_get_attachment_image( $logo_id, 'full', false, $attrs ); 64 } 65 30 66 /** Whether site-title text should be displayed. */ 31 67 function codersly_shop_should_show_site_title() { … … 46 82 function codersly_shop_site_branding() { 47 83 $home = esc_url( home_url( '/' ) ); 48 $has_logo = codersly_shop_branding_show_logo() 49 && function_exists( 'has_custom_logo' ) && has_custom_logo(); 84 $has_logo = codersly_shop_branding_show_logo() && codersly_shop_has_header_logo(); 50 85 $show_title = codersly_shop_should_show_site_title(); 51 86 $show_tagline = codersly_shop_should_show_tagline(); … … 58 93 // 1) Logo. 59 94 if ( $has_logo ) { 60 $custom_logo_id = (int) get_theme_mod( 'custom_logo' ); 61 $logo = wp_get_attachment_image( 62 $custom_logo_id, 63 'full', 64 false, 65 array( 66 'class' => 'site-logo', 67 'style' => 'max-height:var(--bt-logo-h);height:auto;width:auto;', 68 'loading' => 'eager', 69 'decoding' => 'async', 70 ) 71 ); 95 $logo = codersly_shop_header_logo_images( 'site-logo' ); 72 96 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 73 97 echo '<a class="bt-brand-logo" href="' . $home . '" rel="home" aria-label="' . esc_attr__( 'Home', 'codersly-shop' ) . '">' . $logo . '</a>'; -
codersly-shop/1.2.8/languages/codersly-shop.pot
r356755 r357926 4 4 msgid "" 5 5 msgstr "" 6 "Project-Id-Version: Codersly Shop 1.2. 7\n"6 "Project-Id-Version: Codersly Shop 1.2.8\n" 7 7 "Report-Msgid-Bugs-To: https://codersly.com/support\n" 8 8 "POT-Creation-Date: 2026-08-31 16:45+0000\n" -
codersly-shop/1.2.8/readme.txt
r356755 r357926 4 4 Tested up to: 6.9 5 5 Requires PHP: 7.4 6 Stable tag: 1.2. 76 Stable tag: 1.2.8 7 7 License: GPL-2.0-or-later 8 8 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 46 46 47 47 == Changelog == 48 49 = 1.2.8 = 50 * Added independent Desktop and Mobile Sticky Header toggles in Customizer > Headers; mobile defaults off after upgrade. 51 * Increased the mobile header left padding from 8px to 18px, giving the logo and site title more space from the screen edge. 52 * Updated the theme release version metadata to 1.2.8. 48 53 49 54 = 1.2.7 = -
codersly-shop/1.2.8/style.css
r356755 r357926 5 5 Author URI: https://codersly.com/ 6 6 Description: A clean, modern WooCommerce theme for single-store shops. Includes flexible headers, Elementor integration, and widgetized footers. Built for speed, accessibility, and customization via the WordPress Customizer. 7 Version: 1.2. 77 Version: 1.2.8 8 8 Requires at least: 6.3 9 9 Tested up to: 6.9 -
codersly-shop/1.2.8/template-parts/headers/components/logo.php
r356755 r357926 15 15 16 16 $show_logo = codersly_shop_branding_show_logo(); 17 $has_logo = $show_logo && function_exists( 'has_custom_logo' ) && has_custom_logo();17 $has_logo = $show_logo && codersly_shop_has_header_logo(); 18 18 $show_icon = (bool) get_theme_mod( 'codersly_show_site_icon', false ); 19 19 $has_icon = $show_icon && function_exists( 'has_site_icon' ) && has_site_icon(); … … 25 25 26 26 $home_url = esc_url( home_url( '/' ) ); 27 $max_height = codersly_shop_logo_max_height();28 27 29 28 $args = ( … … 44 43 > 45 44 <?php 46 $custom_logo_id = (int) get_theme_mod( 'custom_logo' ); 47 echo wp_get_attachment_image( 48 $custom_logo_id, 49 'full', 50 false, 51 array( 52 'class' => 'bt-logo__img', 53 'style' => 'max-height:' . (int) $max_height . 'px;height:auto;width:auto;', 54 'loading' => 'eager', 55 'decoding' => 'async', 56 ) 57 ); 45 echo codersly_shop_header_logo_images( 'bt-logo__img' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 58 46 ?> 59 47 </a> -
codersly-shop/1.2.8/template-parts/headers/header-1.php
r346202 r357926 23 23 if ( get_theme_mod( 'codersly_shop_header_sticky', false ) ) { 24 24 $classes[] = 'bt-header--sticky'; 25 } 26 // An independent class allows mobile sticky without enabling desktop sticky. 27 if ( get_theme_mod( 'codersly_shop_header_sticky_mobile', false ) ) { 28 $classes[] = 'bt-header--sticky-mobile'; 25 29 } 26 30 ?> … … 158 162 'menu_class' => 'bt-drawer-menu', 159 163 'fallback_cb' => '__return_empty_string', 160 'depth' => 1,164 'depth' => 0, 161 165 ) 162 166 ); -
codersly-shop/1.2.8/template-parts/headers/header-2.php
r356755 r357926 28 28 $classes = array( 'bt-header', 'bt-header--v2', 'bt-header--pro' ); 29 29 30 // Sticky header (desktop only; controlled by Customizer).30 // Desktop sticky (separate mobile toggle below). 31 31 if ( get_theme_mod( 'codersly_shop_header_sticky', false ) ) { 32 32 $classes[] = 'bt-header--sticky'; 33 } 34 // An independent class allows mobile sticky without enabling desktop sticky. 35 if ( get_theme_mod( 'codersly_shop_header_sticky_mobile', false ) ) { 36 $classes[] = 'bt-header--sticky-mobile'; 33 37 } 34 38 ?> … … 137 141 'menu_class' => 'bt-drawer-menu', 138 142 'fallback_cb' => '__return_empty_string', 139 'depth' => 2,143 'depth' => 0, 140 144 ) 141 145 ); -
codersly-shop/1.2.8/template-parts/headers/header-3.php
r356755 r357926 35 35 if ( get_theme_mod( 'codersly_shop_header_sticky', false ) ) { 36 36 $classes[] = 'bt-header--sticky'; 37 } 38 // An independent class allows mobile sticky without enabling desktop sticky. 39 if ( get_theme_mod( 'codersly_shop_header_sticky_mobile', false ) ) { 40 $classes[] = 'bt-header--sticky-mobile'; 37 41 } 38 42 ?> … … 152 156 'menu_class' => 'bt-drawer-menu', 153 157 'fallback_cb' => '__return_empty_string', 154 'depth' => 2,158 'depth' => 0, 155 159 ) 156 160 ); -
codersly-shop/1.2.8/template-parts/headers/header-4.php
r356755 r357926 26 26 $classes = array( 'bt-header', 'bt-header--v4', 'bt-header--pro' ); 27 27 28 // Sticky header toggle (desktop only behavior adjusted in CSS below).28 // Desktop sticky header; mobile has its own independent toggle. 29 29 if ( get_theme_mod( 'codersly_shop_header_sticky', false ) ) { 30 30 $classes[] = 'bt-header--sticky'; 31 } 32 // An independent class allows mobile sticky without enabling desktop sticky. 33 if ( get_theme_mod( 'codersly_shop_header_sticky_mobile', false ) ) { 34 $classes[] = 'bt-header--sticky-mobile'; 31 35 } 32 36 ?> -
codersly-shop/1.2.8/template-parts/headers/header-5.php
r356755 r357926 8 8 * Features: 9 9 * - Sticky on Desktop (when enabled from Customizer) 10 * - Normalon Mobile10 * - Optional independent sticky on Mobile 11 11 * - Drawer menu toggle on Mobile 12 12 * … … 41 41 if ( get_theme_mod( 'codersly_shop_header_sticky', false ) ) { 42 42 $classes[] = 'bt-header--sticky'; 43 } 44 // An independent class allows mobile sticky without enabling desktop sticky. 45 if ( get_theme_mod( 'codersly_shop_header_sticky_mobile', false ) ) { 46 $classes[] = 'bt-header--sticky-mobile'; 43 47 } 44 48 ?> … … 126 130 </header> 127 131 128 <!-- Sticky Desktop / Normal Mobile-->132 <!-- Desktop and mobile sticky options are controlled independently. --> 129 133 130 134 <!-- Mobile header search: page rules are supplied by the Codersly Shop Add-on. --> … … 150 154 'menu_class' => 'bt-drawer-menu', 151 155 'fallback_cb' => '__return_empty_string', 152 'depth' => 2,156 'depth' => 0, 153 157 ) 154 158 );
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)