The repo for Purrform's main BigCommerce store.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

24 cart preview improvements (#25)

authored by

Rogerio Romao and committed by
GitHub
2f6551eb 6e0d8127

+150 -68
+61 -59
assets/scss/components/stencil/navUser/_navUser.scss
··· 17 17 // ----------------------------------------------------------------------------- 18 18 19 19 .navUser { 20 - @include nav($style: "navBar", $wrapper: "nav"); 21 - @include verticalPositionMiddle("absolute"); 20 + @include nav($style: 'navBar', $wrapper: 'nav'); 21 + @include verticalPositionMiddle('absolute'); 22 22 right: 0; 23 23 top: 26px; // 2 24 24 width: 100%; // 4 25 - z-index: zIndex("lowest"); // 5. 25 + z-index: zIndex('lowest'); // 5. 26 26 27 - @include breakpoint("medium") { 28 - padding: 0 spacing("single"); 27 + @include breakpoint('medium') { 28 + padding: 0 spacing('single'); 29 29 position: relative; 30 30 right: auto; 31 31 top: auto; 32 32 transform: none; 33 - z-index: zIndex("high"); 33 + z-index: zIndex('high'); 34 34 } 35 35 36 36 .dropdown-menu { 37 - background-color: stencilColor("navUser-dropdown-backgroundColor"); 38 - border: 1px solid stencilColor("navUser-dropdown-borderColor"); 39 - box-shadow: container("dropShadow"); 37 + background-color: stencilColor('navUser-dropdown-backgroundColor'); 38 + border: 1px solid stencilColor('navUser-dropdown-borderColor'); 39 + box-shadow: container('dropShadow'); 40 40 position: absolute; 41 41 42 42 &.is-open { 43 43 &::before { 44 44 @include css-triangle( 45 - $triangle-direction: "bottom", 45 + $triangle-direction: 'bottom', 46 46 $triangle-size: 10px, 47 - $triangle-color: stencilColor("navUser-dropdown-borderColor") 47 + $triangle-color: 48 + stencilColor('navUser-dropdown-borderColor') 48 49 ); 49 50 bottom: 100%; 50 - left: spacing("half"); 51 + left: spacing('half'); 51 52 position: absolute; 52 53 } 53 54 54 55 &::after { 55 56 @include css-triangle( 56 - $triangle-direction: "bottom", 57 + $triangle-direction: 'bottom', 57 58 $triangle-size: 8px, 58 - $triangle-color: stencilColor("navUser-dropdown-backgroundColor") 59 + $triangle-color: 60 + stencilColor('navUser-dropdown-backgroundColor') 59 61 ); 60 62 bottom: 100%; 61 - left: spacing("half") + remCalc(2px); 63 + left: spacing('half') + remCalc(2px); 62 64 position: absolute; 63 65 } 64 66 } ··· 66 68 } 67 69 68 70 .navUser-section { 69 - @include breakpoint("medium") { 71 + @include breakpoint('medium') { 70 72 position: relative; // 7 71 73 } 72 74 } 73 75 74 76 .navUser-action { 75 - color: stencilColor("navUser-color"); 76 - font-weight: fontWeight("bold"); 77 - padding: spacing("base") spacing("half"); 77 + color: stencilColor('navUser-color'); 78 + font-weight: fontWeight('bold'); 79 + padding: spacing('base') spacing('half'); 78 80 text-decoration: none; 79 81 text-transform: uppercase; 80 82 81 83 &:hover, 82 84 &.is-open { 83 - color: stencilColor("navUser-color-hover"); 85 + color: stencilColor('navUser-color-hover'); 84 86 85 87 svg { 86 - fill: stencilColor("navUser-color-hover"); 87 - stroke: stencilColor("navUser-color-hover"); 88 + fill: stencilColor('navUser-color-hover'); 89 + stroke: stencilColor('navUser-color-hover'); 88 90 } 89 91 } 90 92 91 93 .icon { 92 94 @include square(8px); 93 - margin: -1px 0 0 spacing("eighth"); 95 + margin: -1px 0 0 spacing('eighth'); 94 96 } 95 97 96 98 svg { 97 - fill: stencilColor("navUser-color"); 98 - stroke: stencilColor("navUser-color"); 99 + fill: stencilColor('navUser-color'); 100 + stroke: stencilColor('navUser-color'); 99 101 transition: all 0.15s ease; 100 102 } 101 103 } ··· 103 105 .navUser-action--currencySelector + .dropdown-menu { 104 106 &::before { 105 107 left: auto !important; // 6 106 - right: spacing("half"); // 6 108 + right: spacing('half'); // 6 107 109 } 108 110 109 111 &::after { 110 112 left: auto !important; // 6 111 - right: spacing("half") + remCalc(2px); // 6 113 + right: spacing('half') + remCalc(2px); // 6 112 114 } 113 115 } 114 116 115 117 .navUser-action--storeCredit + .dropdown-menu { 116 118 max-width: remCalc(300px); 117 - padding: spacing("single"); 119 + padding: spacing('single'); 118 120 119 121 &::before { 120 122 left: remCalc(140px) !important; // 3 ··· 126 128 } 127 129 128 130 .navUser-action-divider { 129 - border-right: container("border"); 130 - color: stencilColor("color-textSecondary"); 131 + border-right: container('border'); 132 + color: stencilColor('color-textSecondary'); 131 133 display: inline-block; 132 134 padding: 0 remCalc(20) 0 0; 133 135 text-decoration: none; ··· 136 138 .navUser-item { 137 139 display: none; 138 140 139 - @include breakpoint("medium") { 141 + @include breakpoint('medium') { 140 142 display: block; 141 143 142 144 &.navUser-item--social { ··· 163 165 } 164 166 165 167 .navUser-action { 166 - color: stencilColor("navUser-color"); 168 + color: stencilColor('navUser-color'); 167 169 168 170 &:hover, 169 171 &.is-open { 170 - color: stencilColor("navUser-color-hover"); 172 + color: stencilColor('navUser-color-hover'); 171 173 } 172 174 } 173 175 ··· 178 180 left: auto !important; // 7 179 181 right: remCalc(5px); // 7 180 182 top: auto !important; // 7 181 - @include breakpoint("medium") { 183 + @include breakpoint('medium') { 182 184 right: 0; // 7 183 185 } 184 186 ··· 188 190 } 189 191 190 192 &::before { 191 - right: spacing("half") - remCalc(5px); // 8 192 - @include breakpoint("medium") { 193 - right: spacing("half"); // 8 193 + right: spacing('half') - remCalc(5px); // 8 194 + @include breakpoint('medium') { 195 + right: spacing('half'); // 8 194 196 } 195 197 } 196 198 197 199 &::after { 198 - right: spacing("half") - remCalc(3px); // 8 199 - @include breakpoint("medium") { 200 - right: spacing("half") + remCalc(2px); // 8 200 + right: spacing('half') - remCalc(3px); // 8 201 + @include breakpoint('medium') { 202 + right: spacing('half') + remCalc(2px); // 8 201 203 } 202 204 } 203 205 } ··· 207 209 .navUser-item-cartLabel { 208 210 display: none; 209 211 210 - @include breakpoint("large") { 212 + @include breakpoint('large') { 211 213 display: inline; 212 214 } 213 215 } ··· 233 235 } 234 236 235 237 .navUser-or { 236 - color: stencilColor("navUser-color"); 238 + color: stencilColor('navUser-color'); 237 239 cursor: default; 238 240 display: inline-block; 239 241 margin: 0 remCalc(-12px); ··· 255 257 256 258 &::before { 257 259 @include css-triangle( 258 - $triangle-direction: "bottom", 260 + $triangle-direction: 'bottom', 259 261 $triangle-size: 10px, 260 - $triangle-color: color("greys", "lightest") 262 + $triangle-color: color('greys', 'lightest') 261 263 ); 262 264 bottom: 0; 263 265 left: 50%; ··· 270 272 .dropdown--quickSearch { 271 273 background-color: $dropdown--quickSearch-backgroundColor; 272 274 display: none; 273 - padding: spacing("single") 0; 275 + padding: spacing('single') 0; 274 276 275 - @include breakpoint("small") { 276 - padding: spacing("double"); 277 + @include breakpoint('small') { 278 + padding: spacing('double'); 277 279 } 278 280 279 281 &.is-open { ··· 282 284 outline: none; 283 285 right: 0 !important; // 1 284 286 width: 100% !important; 285 - z-index: zIndex("high"); 287 + z-index: zIndex('high'); 286 288 } 287 289 288 290 .form { ··· 296 298 } 297 299 298 300 .form-input { 299 - font-size: fontSize("small"); 301 + font-size: fontSize('small'); 300 302 height: unset; 301 303 } 302 304 303 305 .productGrid { 304 - padding: spacing("single") 0 0; 306 + padding: spacing('single') 0 0; 305 307 306 - @include breakpoint("small") { 307 - padding: spacing("double") 0 0; 308 + @include breakpoint('small') { 309 + padding: spacing('double') 0 0; 308 310 } 309 311 } 310 312 } ··· 317 319 // ----------------------------------------------------------------------------- 318 320 319 321 .countPill { 320 - background-color: stencilColor("navUser-indicator-backgroundColor"); 322 + background-color: stencilColor('navUser-indicator-backgroundColor'); 321 323 border-radius: 50%; 322 - color: color("whites", "bright"); 324 + color: color('whites', 'bright'); 323 325 display: none; 324 - font-size: fontSize("tiny"); 325 - font-weight: fontWeight("bold"); 326 + font-size: fontSize('tiny'); 327 + font-weight: fontWeight('bold'); 326 328 height: 20px; // 1 327 329 line-height: 20px; // 1 328 - margin-left: spacing("eighth"); 330 + margin-left: spacing('eighth'); 329 331 text-align: center; 330 332 } 331 333 ··· 334 336 } 335 337 336 338 .countPill--alt { 337 - background-color: color("greys", "lighter"); 338 - color: color("greys", "darker"); 339 + background-color: color('greys', 'lighter'); 340 + color: color('greys', 'darker'); 339 341 }
+1 -1
config.json
··· 1 1 { 2 - "name": "product cards redesign", 2 + "name": "cart total preview", 3 3 "version": "6.10.0", 4 4 "template_engine": "handlebars_v4", 5 5 "meta": {
+88 -8
templates/components/common/navigation.html
··· 1 1 <nav class="navUser"> 2 - 2 + 3 3 <div class="grid "> 4 4 <a href="#" class="mobileMenu-toggle" data-mobile-menu-toggle="menu"> 5 5 <span class="mobileMenu-toggleIcon">Toggle menu</span> ··· 13 13 {{> components/common/store-logo}} 14 14 </div> 15 15 {{/if}} 16 - 16 + 17 17 {{#or customer (unless settings.hide_price_from_guests)}} 18 18 {{> components/common/currency-selector}} 19 19 {{/or}} 20 - 20 + 21 21 <ul class="navUser-section navUser-section--alt"> 22 - 22 + 23 23 {{#if customer.store_credit.value '>' 0}} 24 24 <li class="navUser-item"> 25 25 <a class="navUser-action navUser-action--storeCredit" ··· 95 95 <svg width="19" height="18" viewBox="0 0 19 18" fill="none" xmlns="http://www.w3.org/2000/svg"> 96 96 <path fill-rule="evenodd" clip-rule="evenodd" d="M0.617188 0.9C0.617188 0.402944 1.02013 0 1.51719 0H9.61345C10.1105 0 10.5135 0.402944 10.5135 0.9C10.5135 1.39706 10.1105 1.8 9.61345 1.8H2.41719V16.2H9.61719C10.1142 16.2 10.5172 16.6029 10.5172 17.1C10.5172 17.5971 10.1142 18 9.61719 18H1.51719C1.02013 18 0.617188 17.5971 0.617188 17.1V0.9ZM13.0308 4.3136C13.3823 3.96213 13.9521 3.96213 14.3036 4.3136L18.3029 8.31289C18.4953 8.47795 18.6172 8.72287 18.6172 8.99626C18.6172 8.99662 18.6172 8.99697 18.6172 8.99732C18.6179 9.22855 18.53 9.45998 18.3536 9.6364L14.3036 13.6864C13.9521 14.0379 13.3823 14.0379 13.0308 13.6864C12.6793 13.3349 12.6793 12.7651 13.0308 12.4136L15.5481 9.89626H6.01719C5.52013 9.89626 5.11719 9.49332 5.11719 8.99626C5.11719 8.49921 5.52013 8.09626 6.01719 8.09626H15.5407L13.0308 5.5864C12.6793 5.23492 12.6793 4.66508 13.0308 4.3136Z" fill="white"/> 97 97 </svg> 98 - 98 + 99 99 </a> 100 100 <a class="navUser-action" 101 101 href="{{urls.auth.logout}}" ··· 132 132 <svg><use xlink:href="#icon-cart" /> 133 133 </svg> 134 134 <p class="pill-container"><span class="countPill cart-quantity"></span><span class="cart-contents"> Items</span></p> 135 - <!--<span class="navUser-item-cartLabel">{{lang 'common.cart'}}</span>--> 136 - <span class="navUser-item-cartLabel">{{cart.grand_total.formatted}}</span> 135 + <span class="navUser-item-cartLabel"></span> 136 + 137 137 </a> 138 138 <div class="dropdown-menu" id="cart-preview-dropdown" data-dropdown-content aria-hidden="true"></div> 139 139 </li> 140 140 </ul> 141 - 142 141 143 142 143 + 144 144 </div> 145 145 <div class="dropdown dropdown--quickSearch" id="quickSearch" aria-hidden="true" data-prevent-quick-search-close> 146 146 {{> components/common/quick-search name='nav-quick-search'}} 147 147 </div> 148 148 </nav> 149 + 150 + <script> 151 + async function getCartTotal() { 152 + const cartId = '{{ cart_id }}'; 153 + 154 + const query = ` 155 + query site { 156 + site { 157 + cart(entityId: "${cartId}") { 158 + entityId 159 + amountInDisplayCurrency { 160 + value 161 + currencyCode 162 + formattedV2 163 + } 164 + } 165 + } 166 + } 167 + `; 168 + 169 + try { 170 + const response = await fetch('/graphql', { 171 + method: 'POST', 172 + credentials: 'same-origin', 173 + headers: { 174 + 'Content-Type': 'application/json', 175 + 'Authorization': `Bearer {{ settings.storefront_api.token }}` 176 + }, 177 + body: JSON.stringify({ 178 + query: query, 179 + variables: { cartId: cartId } 180 + }) 181 + }); 182 + 183 + const result = await response.json(); 184 + const formattedTotal = result.data.site.cart?.amountInDisplayCurrency?.formattedV2 || ''; 185 + return formattedTotal; 186 + } catch (error) { 187 + return null; 188 + } 189 + } 190 + 191 + document.addEventListener('DOMContentLoaded', () => { 192 + getCartTotal().then(formattedTotal => { 193 + document.querySelector('.navUser-item-cartLabel').textContent = formattedTotal; 194 + }).catch(error => { 195 + console.error('Error getting cart total:', error); 196 + document.querySelector('.navUser-item-cartLabel').textContent = ''; 197 + }); 198 + }); 199 + 200 + // Select the node that will be observed for mutations 201 + const targetNode = document.querySelector('.navUser-item--cart'); 202 + 203 + // Options for the observer (which mutations to observe) 204 + const config = { attributes: false, childList: true, subtree: true }; 205 + 206 + // Callback function to execute when mutations are observed 207 + const callback = (mutationList, observer) => { 208 + for (const mutation of mutationList) { 209 + if (mutation.type === "childList") { 210 + // if the child node that changed is the cart quantity, update the cart total 211 + if (mutation.target.classList.contains('countPill')) { 212 + getCartTotal().then(formattedTotal => { 213 + document.querySelector('.navUser-item-cartLabel').textContent = formattedTotal; 214 + }).catch(error => { 215 + document.querySelector('.navUser-item-cartLabel').textContent = ''; 216 + }); 217 + } 218 + } 219 + } 220 + }; 221 + 222 + // Create an observer instance linked to the callback function 223 + const observer = new MutationObserver(callback); 224 + 225 + // Start observing the target node for configured mutations 226 + observer.observe(targetNode, config); 227 + 228 + </script>