From ce5e05c3df00ef0887d5d5a820ebe6a67d8b5698 Mon Sep 17 00:00:00 2001 From: Brandon Comerford Date: Thu, 28 Sep 2023 20:31:33 -0500 Subject: [PATCH] Cornerstone update 5.5.0 (#47) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fixed slick issue with cloning slides * Releasing 4.10.0-rc.6 * Fix * Releasing 4.10.0-rc.7 * Refactor GitHub action for Bundle Test (#1852) Making a few improvements to the GitHub action which does a test bundle. * Better docs/comments * Better name * Support "master" or "main" branch as new forks will use `main` * https://www.zdnet.com/article/github-to-replace-master-with-main-starting-next-month/ * https://github.com/github/renaming * Add both a ruby gem cache as well as an npm cache to speed things up (CLI install is most of the time spent currently) * Update Test Badge in README.md * Upload bundled .zip file on PRs for easy testing * Releasing 4.10.0 * Cornerstone 4.10 changelog update * fix(storefront): BCTHEME-171 State of search link not announced (#1798) * fix(storefront): BCTHEME-198 Face accessibility standards with social links on PDP's page (#1809) * fix(storefront): BCTHEME-215 Delete item button in cart cut off from right side when in focus (#1823) * fix(storefront): BCTHEME-169 Subscription notification not announced (#1813) * feat(storefront)bctheme-203: add sufficient contrast on checkboxes within faceted search (#1815) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * fix(storefront): BCTHEME-167 Focus not visible on logo element (#1800) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * feat(storefront):BCTHEME-168: addcontrast for email address input according to AA standard (#1804) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * feat(storefront):BCTHEME-174 add contrast on product ratings in Quick View (#1799) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * feat(storefront):bctheme-173: add color for carousel arrows AA standard (#1814) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * feat(storefront)bctheme-220: add sufficient contrast to button border color (#1817) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * BCTHEME-229 Product carousel with related products - arrows not working (#1828) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * fix(storefront)BCTHEME170: fix empty cart notification (#1846) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * feat(cornerstone):BCTHEME-201: add expanded/collapsed state on add-info button (#1844) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * fix(storefront)bctheme-223: fix voiceover focus not sync in faceted search (#1826) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * feat(storefront)BCTHEME75: add keyboard focus on write-a-review modal (#1835) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * fix(storefront)bctheme-225:fix filter top outline on focus (#1829) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * fix(storefront)BCTHEME-224: change role for sort by select (#1837) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * fix(storefront):bctheme-212 fix rating icons focus border (#1819) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * fix(storefront)BCTHEME-216: fix outline styles for breadcrumbs on focus (#1824) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * Fixed merge conflict * feat(content): MERC-7162 Add header bottom global region * Removed broken import from tools.scss file * BCTHEME-213 Add Info and Add Coupon forms on Cart Page tabbable when hidden (#1820) * Releasing 4.11.0-rc.1 * Update GitHub Action to use Node 12 Node 12 is now supported for Stencil CLI, so we'll use it for this action going forward. * Add examples of useful GitHub Actions for theme development * Releasing 4.11.0 * fix(payments): INT-3211 Change width size for apple pay button * Update Changelog * feat(storefront): STRF-8630 update cornerstone to be compatible with handlebars v4 * fix(storefront): BCTHEME-197 Logo focus of voice over has wrong (100% of the screen) width (#1831) * fix(storefront): BCTHEME-222 Rating and Other filter sections are not accessible by keyboard (#1838) * BCTHEME-210 Carousel hidden when one or more of its images not found (#1816) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * BCTHEME-214 Wishlist first option has no bottom outline when in focus (#1825) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * fix(storefront): BCTHEME-217 Product link has incorrect voice over focus on Cart Page (#1830) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * fix(storefront): BCTHEME-172 Card content truncated on zooming browser to 400% (#1803) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * BCTHEME-185 Sort By dropdowns need visual focus border (#1833) * BCTHEME-188 Product cards should link to products (#1842) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * BCTHEME-184 Options on change modal need focus border (#1839) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * BCTHEME-199 Zooming and scaling must not be disabled (#1843) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * BCTHEME-202 Notification of number of products not announced (#1845) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * BCTHEME-190 Content should not scroll in two directions when zoomed (#1853) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * feat(storefront)BCTHEME-205: add filter reset announcement (#1858) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * feat(storefront) BCTHEME-206: add announcement fot filtered result on Shop-by-price (#1854) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * fix(storefront)BCTHEME-164: fix image in modal for IE11 (#1840) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * fix(storefront): BCTHEME-279 fix logo displaying (#1865) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * feat(storefront):add to cart notification (#1860) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * BCTHEME-44 Cornerstone quick view (#1857) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * fix(storefront): BCTHEME-277 Certain Special Characters not rendering under Wishlists (#1873) * fix(storefront): BCTHEME-219 Social icons not clickable in modal after reopening (#1874) * fix(storefront): BCTHEME-282 Fix aria-labels for collapsibleFactory elements (#1868) * BCTHEME-269 Remove layout shifts to improve CLS indicator from Lighthouse performance report (#1869) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * fix(storefront): BCTHEME-233 Cornerstone - Unable to Compare Products from Recently Viewed Items (#1877) * feat(storefront): BCTHEME-290 add aria labelwith price for product list item (#1878) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * BCTHEME-209 Search result not notified by screen reader (#1867) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * fix(storefront): BCTHEME-289 Add aria label with price to Product Grid Item (#1875) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * fix(storefront): BCTHEME-268 Update carousel images to improve LCP indicator from Lighthouse performance report (#1876) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * feat(storefront): BCTHEME-187 improve localization and add default and fallback messages (#1850) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * fix(storefront): BCTHEME-297 Cornerstone 4.11.0 - Product Image Carousel Becomes Unresponsive on Product Page (#1879) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * Resolved issues after merging PRs for 4.12 release * Releasing 4.12.0-rc.1 * Reduce lodash usage in compare-products.js and image-gallery.js * Releasing 4.12.0-rc.2 * Releasing 4.12.0-rc.3 * Releasing 4.12.0-rc.4 * Upload bundle analysis as part of github action * feat(search): ES-1590 display error message if search fails * feat: (STRF-8747) add new stencil config files to .gitignore * Releasing 4.12.0 * Revert "Releasing 4.12.0" * feat(storefront): BCTHEME-299 update changelog for release 4.12 * Releasing 4.12.0 * Updated CHANGELOG.md before 4.12 release * Reverting cornerstone version to 4.12-rc.4 * Releasing 4.12.0 * Reverting 4.12 changes * Releasing 4.12.0 * Reverted 4.12 release commit and updated package.json versions * Releasing 4.12.0 * Revert fix(storefront): BCTHEME-219 Social icons not clickable in modal * Don't load social icons in quick view * Bump stencil-utils * fix(storefront): BCTHEME-305 Price Lists - Price in the cart is not updated when changing currency on mobile * fix(storefront): BCTHEME-314 ccount >Payment Methods throws Server Error when using Cornerstone theme (#1898) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * fix(storefront): BCTHEME-315 Write a Review modal cause TypeError (#1899) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * Releasing 4.12.1 * feat(payments): PAYPAL-712 Checkout page - Smart Payment Button styli… (#1866) feat(payments): PAYPAL-712 Checkout page - Smart Payment Button styling (Cornerstone) * feat(storefront): BCTHEME-116 move tax field after grand total when tax inclusive (#1903) * fix(storefront): BCTHEME-105 Cornerstone - Body text size above 14px is cut off on cart shipping dropdowns (#1881) * feat(storefront): BCTHEME-69 Add tooltips for carousel bullets (buttons) (#1889) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * fix(storefront): BCTHEME-319 Write a review modal extra executions (#1902) (#1902) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * fix(storefront): BCTHEME-232 Faceted search filters are hidden from screen readers (#1897) * fix(storefront): BCTHEME-292 Social icon tooltip displaying should be fixed (#1907) * BCTHEME-293 Product list item Quick view button is not tabbable (#1900) (#1900) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * fix(storefront): BCTHEME-273 fix contrast ratio for Skip to Main Content element (#1880) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * feat(storefront): BCTHEME-275 add upsell banner contrast (#1891) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * fix(storefront): BCTHEME-274 fix contranst ratio for brand name (#1882) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * fix(storefront): BCTHEME-288 Shoppers are not anchor-linked to reviews on PDPs if product description tabs are enabled (#1883) * fix(storefront): BCTHEME-308 HTML Entity displayed as is via system/error message on a Storefront (#1888) * STRF-8769 Moved zoomSize and productSize to the upper level, cause product.js is not availabe on the Quick View (#1884) * Bump versions of Ruby (#1905) To fix issue #1904 * Changelog update * fix(storefront): BCTHEME-104 Selecting product options doesn't update image on PDP in Internet Explorer (#1913) * fix(storefront): BCTHEME-11 hide product options that are out of stock on cart (#1911) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * fix(storefront): BCTHEME-301 Header content placed out of the header block on mobile (#1908) (#1908) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * fix(storefront): BCTHEME-85 “Sort by” dropdown selection not reflected on search results page for News and Information tab (#1910) (#1910) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * fix(storefront): BCTHEME-86 Cornerstone - Text hover color does not change when Dropdown menu display mode is set to Alternative (#1918) (#1918) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * fix(storefront): BCTHEME-321 fix social icon tooltip overlaying (#1914) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * Resolving eslint error after merging * fix(storefront): BCTHEME-30 fix misaligned tooltip for required product option (#1915) Co-authored-by: yurytut1993 <66325265+yurytut1993@users.noreply.github.com> * fix(storefront): BCTHEME-87 Product images squashed in Category view in AMP (#1921) (#1921) * fix(storefront): BCTHEME-313 Parse HTML entities in jsContext (#1917) * Added Changelog item for BCTHEME-313 * Releasing 5.0.0-rc.1 * feat(payments): PAYPAL-823 Add new banner on the cart page (#1901) * Releasing 5.0.0-rc.2 * Releasing 5.0.0 * feat(storefront): BCTHEME-304 add pagination for wishlists (#1906) * fix(storefront): BCTHEME-341 fix placeholder contrast ratio (#1933) * fix(storefront): BCTHEME-37 Cornerstone - Image Zoom Does Not Work on Internet Explorer (#1923) (#1923) * feat(storefront): BCTHEME-306 show price range on option selection (#1924) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * fix(storefront): BCTHEME-16 Cornerstone - loading of thumbnail image delayed on cart page (#1925 (#1925) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * fix(storefront): BCTHEME-193 fix not being able to change product qty with keyboard multiple times (#1927) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * fix(storefront): BCTHEME-345 define a main region on pages (#1929) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * fix(storefront): BCTHEME-346 add announcement for shipping estimator error messages (#1932) Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> * feat(storefront): BCTHEME-343 No tooltips provided for carousel buttons (#1934) (#1934) * feature(storefront): Empty cart message not read by screen reader (#1935) (#1935) * feat(storefront): BCTHEME-344 Carousel buttons do not receive focus (#1937) (#1937) * fix(storefront): BCTHEME-155 fix recaptcha announcement for hidden content (#1943) * fix(storefront): BCTHEME-379 fix non-text contrast on add to cart button (#1946) * fix(storefront): BCTHEME-369 fix announcement on adding to cart by screen reader (#1950) * feat(storefront): BCTHEME-373 Alt text not provided for ratings (#1949) * feat(storefront): BCTHEME-78 Add Play/Pause button to carousel (#1944) * fix(storefront): BCTHEME-366 Error message on PLPs not announced by screen reader (#1956) * fix(storefront): BCTHEME-361 fix subscription message announcement (#1952) * feat(payments): PAYPAL-903 Product Page Banners (Cornerstone) - creat… (#1948) * feat(payments): PAYPAL-903 Product Page Banners (Cornerstone) - create custom price event * feat(payments): PAYPAL-903 Product Page Banners (Cornerstone) - create custom price event - CR fixes Co-authored-by: Alex Saiannyi <67792608+bc-alexsaiannyi@users.noreply.github.com> * BCTHEME-327: PDP - Empty "Description" is Hiding All Tabs When in Tab View (#1947) * feat(storefront): BCTHEME-388 Dots on carousel should have similar colours as other slider controls (#1958) * fix(storefront): BCTHEME-384 When default option is out of stock add to cart button does not populate for in stock options (#1955) * fix(storefront): BCTHEME-383 Selecting certain option types pushes window view to the bottom of the page (#1959) * Fixed merge conflict * STRF-8898 'Show More' gives no additional options when filter clicked (#1945) * Releasing 5.1.0-rc.1 * BCTHEME-387: Updates Cornerstone variants to meet the updated verticals outlined in BCTHEME-387. (#1962) Co-authored-by: Dante Muñoz * Releasing 5.1.0-rc.2 * Releasing 5.1.0 * feat(storefront): STRF-8948 Fix Sort By on Search Page (#1971) * fix(storefront): BCTHEME-368 fix announcement for shop by price filter selection (#1966) * fix(storefront): BCTHEME-207 fix focus on sort by (#1964) * fix(storefront): BCTHEME-385 move a phrase from html to en.json (#1972) * feat(storefront): BCTHEME-390 Integrate accessibility scripts to product images slider on PDP (#1965) * fix(storefront): BCTHEME-354 If multiple Pick List Options are applied, customers cannot select 'none' on both (#1975) * fix(storefront): BCTHEME-356 Required checkbox message blocks the checkbox (#1963) * Updated Changelog PR link for BCTHEME-212 Fixed review rating icons focus border. * feat(storefront): BCTHEME-391 Move focus on filter items Modal after show more button was clicked and accessibility refactoring (#1977) * feat(storefront) BCTHEME-381 add suffient text for swatch option (#1976) * fix(storefront): BCTHEME-398 Make every product option group id unique (#1979) * fix(storefront): BCTHEME-264 fix update discount banner on PDP (#1974) * fix(storefront): BCTHEME-372 Error message not announced automatically (#1983) * fix(storefront): BCTHEME-400 If product options are not required, the 'None' option will remain selected even if another option is chosen (#1980) * fix(storefront): BCTHEME-334 Add alt attribute for no image placeholders (#1984) * fix(storefront): BCTHEME-401 Category pages are creating alt attribute within the span tag (#1987) * fix(storefront): BCTHEME-362 fix cut off cart button on zooming 400 (#1988) * Releasing 5.2.0-rc.1 * Releasing 5.2.0 * Reverting 5.2.0 to 5.2.0-rc.1 * Releasing 5.2.0 * Revert "Releasing 5.2.0" * Releasing 5.2.0 * Revert "Releasing 5.2.0" 2nd time * Releasing 5.2.0 * feat(storefront): BCTHEME-200 add notifications announcement on carousel change (#1986) * fix(storefront): BCTHEME-392 fixed line breaks on Dropdown Menu (#1996) * fix(storefront): BCTHEME-347 Add unique identifiers to product cards (#1999) * fix(storefront): BCTHEME-409 Update focus trap in Modal (#1998) * fix(search): ES-2031 add error message for when star search is not availabble in facted search * feat(search): ES-1590 render error msg for brand page * fix(search): ES-2031 make search error more generic * feat(search): ES-2031 add change to changelog * feat(storefront): BCTHEME-322 add sold-out badges for products on PLP (#2003) * BCTHEME-426: Insufficient link text for "Read More" links (#2012) * BCTHEME-422: Announce email field as mandatory (#2011) * BCTHEME-420: 'Skip to main content' is not visible (#2010) * fix(storefront): BCTHEME-427 Insufficient button label on cart page (#2013) * feat(storefront): BCTHEME-231 Add placeholder for failed to load carousel images and update scalability (#2009) * fix(storefront): BCTHEME-429 Unlabelled edit fields on cart page (#2016) * fix(storefront): BCTHEME-428 Insufficient link text on cart page (#2014) * fix(storefront): BCTHEME-424 Alt text should include product name for ratings (#2015) * fix(storefront): IE11 - Clicking on Search Does Not Display Search Bar (#2017) * Releasing 5.3.0-rc.1 * Fixing 'Skip to main' content mobile display * Releasing 5.3.0-rc.2 * Releasing 5.3.0 * Revert Releasing 5.3.0 * Remove AddThis for social sharing, replace with provider sharing links (#1997) * Updated changelog * Releasing 5.3.0 * fix(search): ES-2071 removed adding selected filters for price filter since not needed (#2018) * fix(storefront): BCTHEME-431 remove horizontal scroll on swatch options PDP (#2023) * fix(search): ES-2138 fixed count showing issue for category facet * fix(storefront): BCTHEME-349 improve email validation for forms (#2029) * feat(storefront): BCTHEME-445 replace page builder ssl settings with new global region for html widget (#2026) * fix(storefront): BCTHEME-447 extend keyboard support for radio buttons (#2028) * feat(storefront): BCTHEME-446 Improve performance of analyzing homepage carousel image (#2027) * fix(storefront): BCTHEME-395 Wish List drop down is truncated on product page (#2001) * fix(storefront): BCTHEME-434 Hamburger Menu Icon missing on Google AMP Pages (#2022) * fix(storefront): BCTHEME-449 remove main tag duplicates (#2032) * feat(storefront): BCTHEME-425 Incorrect focus order for product carousels (#2034) * Releasing 5.4.0-rc.1 * fix(storefront): DEV-426 Fix GitHub workflows for default storefront * Releasing 5.4.0 * fix(storefront): BCTHEME-325 Apple pay button displaying needs to be fixed (#2043) * fix(storefront): BCTHEME-457 Update focus tooltip styles contrast to achieve accessibility AA Complaince (#2047) * Use https:// for schema markup (#2039) * fix(storefront): BCTHEME-423 Search result on search page not notified by screen reader (#2024) * feat(payment): PAYPAL-968 added banner widgets to page builder (#2021) * fix(storefront): bctheme-448 fix multiple swatch options (#2040) * feat(storefront): BCTHEME-476 Scale focus trap for all modals (#2049) * Releasing 5.5.0-rc.1 * Releasing 5.5.0 --------- Co-authored-by: Tymur Biedukhin Co-authored-by: Nathan Booker Co-authored-by: BC-tymurbiedukhin <66319629+BC-tymurbiedukhin@users.noreply.github.com> Co-authored-by: Alex Saiannyi <67792608+bc-alexsaiannyi@users.noreply.github.com> Co-authored-by: yurytut1993 <66325265+yurytut1993@users.noreply.github.com> Co-authored-by: Erik Christensen Co-authored-by: Juned Kazi Co-authored-by: Nathan Booker Co-authored-by: Marco Loyo Co-authored-by: Jairo Panduro Co-authored-by: Pascal Zajac Co-authored-by: Yurii Zusik Co-authored-by: sacr3dc0w Co-authored-by: alex.saiannyi Co-authored-by: Kevin Wang Co-authored-by: MaxGenash Co-authored-by: David Huynh Co-authored-by: Andrii Fetisov <54856617+bc-fetisov@users.noreply.github.com> Co-authored-by: jairo-bc <68893868+jairo-bc@users.noreply.github.com> Co-authored-by: Andrew A. Barber Co-authored-by: Brian Davenport Co-authored-by: Olga Lashkul <32959076+helga1507@users.noreply.github.com> Co-authored-by: Dante Munoz <35115108+DanteMunoz@users.noreply.github.com> Co-authored-by: Dante Muñoz Co-authored-by: Nataliya Solyanik Co-authored-by: bc-krishsenthilraj <39140274+bc-krishsenthilraj@users.noreply.github.com> Co-authored-by: Senthil Krishnasamy Co-authored-by: Yevhenii Buliuk <82589781+bc-yevhenii-buliuk@users.noreply.github.com> Co-authored-by: Andrii Vitvitskyi --- .../automatic_deployment_production.yml | 4 +- .../poll_for_changed_configuration.yml | 5 + CHANGELOG.md | 23 +- .../js/test-unit/theme/global/modal.spec.js | 3 + assets/js/theme/cart.js | 8 + assets/js/theme/common/aria/radioOptions.js | 8 +- assets/js/theme/common/carousel/constants.js | 1 + assets/js/theme/common/carousel/index.js | 51 ++-- .../carousel/utils/activatePlayPauseButton.js | 48 ++-- .../common/carousel/utils/analizeSlides.js | 14 ++ .../common/carousel/utils/arrowAriaLabling.js | 15 +- .../theme/common/carousel/utils/dotsSetup.js | 4 +- .../getActiveSlideIdxAndSlidesQuantity.js | 2 +- .../carousel/utils/getActiveSlideInfo.js | 10 +- .../carousel/utils/handleImageAspectRatio.js | 35 +-- .../common/carousel/utils/handleImageLoad.js | 39 ++- .../js/theme/common/carousel/utils/index.js | 4 +- .../common/carousel/utils/refreshFocus.js | 20 ++ .../common/carousel/utils/tooltipSetup.js | 20 +- assets/js/theme/common/faceted-search.js | 2 +- assets/js/theme/common/models/forms.js | 2 +- assets/js/theme/common/product-details.js | 76 +++++- assets/js/theme/common/utils/ie-helpers.js | 2 +- assets/js/theme/global/cart-preview.js | 4 + assets/js/theme/global/modal.js | 18 ++ assets/js/theme/global/quick-view.js | 9 +- assets/js/theme/search.js | 12 +- assets/scss/common/_focus-tooltip.scss | 6 +- .../stencil/applePay/_applePay.scss | 11 +- .../scss/components/stencil/cart/_cart.scss | 16 +- .../stencil/heroCarousel/_heroCarousel.scss | 37 +++ .../stencil/previewCart/_previewCart.scss | 5 +- .../stencil/productView/_productView.scss | 3 +- .../scss/components/vendor/slick/_slick.scss | 3 - .../vendor/sweetalert2/_sweetalert2.scss | 4 + assets/scss/layouts/header/_header.scss | 28 +-- assets/scss/settings/global/color/_color.scss | 7 +- config.json | 21 +- package-lock.json | 4 +- package.json | 2 +- schema.json | 224 +++++++++++++++--- schemaTranslations.json | 97 +++++--- .../amp/products/product-view-details.html | 2 +- .../components/amp/products/reviews.html | 4 +- templates/components/common/body.html | 2 +- templates/components/common/breadcrumbs.html | 4 +- templates/components/common/footer.html | 11 +- templates/components/common/share.html | 117 +++++---- templates/components/common/store-logo.html | 2 +- .../faceted-search/facets/hierarchy.html | 4 +- .../faceted-search/facets/range.html | 3 - .../components/products/add-to-cart.html | 2 +- .../components/products/options/swatch.html | 4 +- .../components/products/price-range.html | 20 +- templates/components/products/price.html | 20 +- .../components/products/product-view.html | 29 +-- templates/components/products/reviews.html | 4 +- templates/pages/account/add-return.html | 4 +- templates/pages/account/inbox.html | 4 +- templates/pages/account/orders/all.html | 4 +- templates/pages/account/returns.html | 4 +- templates/pages/amp/category.html | 4 +- templates/pages/amp/product.html | 2 +- templates/pages/auth/account-created.html | 4 +- templates/pages/blog.html | 4 +- templates/pages/brand.html | 4 +- templates/pages/brands.html | 4 +- templates/pages/cart.html | 4 +- templates/pages/category.html | 4 +- templates/pages/compare.html | 4 +- templates/pages/contact-us.html | 4 +- templates/pages/errors/403.html | 4 +- templates/pages/errors/404.html | 4 +- templates/pages/errors/generic.html | 4 +- templates/pages/gift-certificate/balance.html | 4 +- .../pages/gift-certificate/purchase.html | 4 +- templates/pages/gift-certificate/redeem.html | 4 +- templates/pages/page.html | 4 +- templates/pages/product.html | 2 +- templates/pages/search.html | 13 +- 80 files changed, 828 insertions(+), 404 deletions(-) create mode 100644 assets/js/theme/common/carousel/constants.js create mode 100644 assets/js/theme/common/carousel/utils/analizeSlides.js create mode 100644 assets/js/theme/common/carousel/utils/refreshFocus.js diff --git a/.github/workflow-examples/automatic_deployment_production.yml b/.github/workflow-examples/automatic_deployment_production.yml index 3565324e91..5f3c18e73d 100644 --- a/.github/workflow-examples/automatic_deployment_production.yml +++ b/.github/workflow-examples/automatic_deployment_production.yml @@ -39,6 +39,8 @@ jobs: # # You must configure store credentials as secrets on your GitHub repo for automatic deployment via GitHub Actions +# This defaults to pushing the theme to channel ID 1, which is the default storefront. If you wish to push to an +# Alternate storefront, use a different channel ID # - name: Connect to store @@ -48,4 +50,4 @@ jobs: run: stencil init -u $URL -t $TOKEN -p 3000 - name: Push theme live, automatically deleting oldest theme if necessary - run: stencil push -a -d + run: stencil push -a -d -c 1 diff --git a/.github/workflow-examples/poll_for_changed_configuration.yml b/.github/workflow-examples/poll_for_changed_configuration.yml index 3bba3e3fe6..6420f8d96a 100644 --- a/.github/workflow-examples/poll_for_changed_configuration.yml +++ b/.github/workflow-examples/poll_for_changed_configuration.yml @@ -49,8 +49,13 @@ jobs: TOKEN: ${{ secrets.STENCIL_ACCESS_TOKEN_PRODUCTION }} run: stencil init -u $URL -t $TOKEN -p 3000 +<<<<<<< HEAD - name: Check for an updated configuration on the live store run: stencil pull +======= + - name: Check for an updated configuration on the live default storefront (channel ID 1) + run: stencil pull -c 1 +>>>>>>> 5.5.0 - name: Create Pull Request id: cpr diff --git a/CHANGELOG.md b/CHANGELOG.md index e0146abfbd..589491997a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,28 @@ ## Draft -## 5.3.0 (03-24-2021) +## 5.5.0 (05-20-2021) +- Scale focus trap for all modals. [#2049](https://github.com/bigcommerce/cornerstone/pull/2049) +- Fixed displaying swatch name for multiple swatch options on page. [#2040](https://github.com/bigcommerce/cornerstone/pull/2040) +- Added settings for payment banners. [#2021](https://github.com/bigcommerce/cornerstone/pull/2021) +- Use https:// for schema markup. [#2039](https://github.com/bigcommerce/cornerstone/pull/2039) +- Update focus tooltip styles contrast to achieve accessibility AA Complaince. [#2047](https://github.com/bigcommerce/cornerstone/pull/2047) +- Apple pay button displaying needs to be fixed. [#2043](https://github.com/bigcommerce/cornerstone/pull/2043) + +## 5.4.0 (04-26-2021) +- Incorrect focus order for product carousels. [#2034](https://github.com/bigcommerce/cornerstone/pull/2034) +- Removed duplicates of main tag.[#2032](https://github.com/bigcommerce/cornerstone/pull/2032) +- Hamburger Menu Icon missing on Google AMP Pages. [#2022](https://github.com/bigcommerce/cornerstone/pull/2022) +- Wish List drop down is truncated on product page. [#2001](https://github.com/bigcommerce/cornerstone/pull/2001) +- Improve performance of analyzing homepage carousel images. [#2027](https://github.com/bigcommerce/cornerstone/pull/2027) +- Added keyboard support on radio buttons. [#2028](https://github.com/bigcommerce/cornerstone/pull/2028) +- Replace SSL settings in Page builder with global region for SSL certificate. [#2026](https://github.com/bigcommerce/cornerstone/pull/2026) +- fixed email address validation in forms. [#2029](https://github.com/bigcommerce/cornerstone/pull/2029) +- Fixed unnecessary horizontal scroll on swatch options on PDP. [#2023](https://github.com/bigcommerce/cornerstone/pull/2023) +- Always showing product counts for Category facet in the faceted search results page. [#2035](https://github.com/bigcommerce/cornerstone/pull/2035) + +## 5.3.0 (03-25-2021) +- Remove AddThis for social sharing, replace with provider sharing links. [#1997](https://github.com/bigcommerce/cornerstone/pull/1997) - IE11 - Clicking on Search Does Not Display Search Bar. [#2017](https://github.com/bigcommerce/cornerstone/pull/2017) - Alt text should include product name for ratings. [#2015](https://github.com/bigcommerce/cornerstone/pull/2015) - Changed insufficient "Change" link text on cart page. [#2014](https://github.com/bigcommerce/cornerstone/pull/2014) diff --git a/assets/js/test-unit/theme/global/modal.spec.js b/assets/js/test-unit/theme/global/modal.spec.js index 459e2ede9b..ce4684dd9b 100644 --- a/assets/js/test-unit/theme/global/modal.spec.js +++ b/assets/js/test-unit/theme/global/modal.spec.js @@ -16,6 +16,9 @@ describe('Modal', () => { beforeEach(() => { $element = attachHtml(` diff --git a/assets/js/theme/cart.js b/assets/js/theme/cart.js index 1c26e4690b..139147c404 100644 --- a/assets/js/theme/cart.js +++ b/assets/js/theme/cart.js @@ -10,6 +10,7 @@ import CartItemDetails from './common/cart-item-details'; export default class Cart extends PageManager { onReady() { this.$modal = null; + this.$cartPageContent = $('[data-cart]'); this.$cartContent = $('[data-cart-content]'); this.$cartMessages = $('[data-cart-status]'); this.$cartTotals = $('[data-cart-totals]'); @@ -18,9 +19,16 @@ export default class Cart extends PageManager { this.$activeCartItemId = null; this.$activeCartItemBtnAction = null; + this.setApplePaySupport(); this.bindEvents(); } + setApplePaySupport() { + if (window.ApplePaySession) { + this.$cartPageContent.addClass('apple-pay-supported'); + } + } + cartUpdate($target) { const itemId = $target.data('cartItemid'); this.$activeCartItemId = itemId; diff --git a/assets/js/theme/common/aria/radioOptions.js b/assets/js/theme/common/aria/radioOptions.js index f65eb29827..5a32129994 100644 --- a/assets/js/theme/common/aria/radioOptions.js +++ b/assets/js/theme/common/aria/radioOptions.js @@ -9,6 +9,7 @@ const setCheckedRadioItem = (itemCollection, itemIdx) => { } $item.attr('aria-checked', true).prop('checked', true).focus(); + $item.trigger('change'); }); }; @@ -31,21 +32,18 @@ const handleItemKeyDown = itemCollection => e => { } switch (keyCode) { - case ariaKeyCodes.RETURN: - case ariaKeyCodes.SPACE: { - setCheckedRadioItem(itemCollection, itemIdx); - break; - } case ariaKeyCodes.LEFT: case ariaKeyCodes.UP: { const prevItemIdx = calculateTargetItemPosition(lastCollectionItemIdx, itemIdx - 1); itemCollection.get(prevItemIdx).focus(); + setCheckedRadioItem(itemCollection, itemIdx - 1); break; } case ariaKeyCodes.RIGHT: case ariaKeyCodes.DOWN: { const nextItemIdx = calculateTargetItemPosition(lastCollectionItemIdx, itemIdx + 1); itemCollection.get(nextItemIdx).focus(); + setCheckedRadioItem(itemCollection, itemIdx + 1); break; } diff --git a/assets/js/theme/common/carousel/constants.js b/assets/js/theme/common/carousel/constants.js new file mode 100644 index 0000000000..9db53bebe6 --- /dev/null +++ b/assets/js/theme/common/carousel/constants.js @@ -0,0 +1 @@ +export const FOCUSABLE_ELEMENTS_SELECTOR = '[href], button, input, textarea, select, details, [contenteditable="true"], [tabindex]'; diff --git a/assets/js/theme/common/carousel/index.js b/assets/js/theme/common/carousel/index.js index 1cdc858699..a687f11035 100644 --- a/assets/js/theme/common/carousel/index.js +++ b/assets/js/theme/common/carousel/index.js @@ -2,62 +2,61 @@ import 'slick-carousel'; import { activatePlayPauseButton, + analizeSlides, arrowAriaLabling, dotsSetup, getActiveSlideIdxAndSlidesQuantity, handleImageAspectRatio, handleImageLoad, - setTabindexes, - tooltipSetup, + refreshFocus, updateTextWithLiveData, } from './utils'; -/** - * returns activeSlideIdx and slidesQuantity - * based on provided carousel settings - * @param {Object} $slickSettings - * @returns {Object} - */ -const extractSlidesDetails = ({ - slideCount, $slides, options: { slidesToShow, slidesToScroll }, -}) => getActiveSlideIdxAndSlidesQuantity( - slideCount, - slidesToShow, - slidesToScroll, - $slides, -); +export const setCarouselState = ({ delegateTarget }, carouselObj) => { + const carouselObjCurrent = carouselObj || delegateTarget.slick; + const { $slider } = carouselObjCurrent; + + $slider.data('state', getActiveSlideIdxAndSlidesQuantity(carouselObjCurrent)); +}; export const onUserCarouselChange = ({ data }, context, $slider) => { const $activeSlider = $slider || data; - const $parentContainer = $activeSlider.hasClass('productView-thumbnails') ? $('.productView-images') : $activeSlider; - const { activeSlideIdx, slidesQuantity } = extractSlidesDetails($activeSlider[0].slick); + const $parentContainer = $activeSlider.hasClass('productView-thumbnails') ? $activeSlider.parent('.productView-images') : $activeSlider; + const { activeSlideIdx, slidesQuantity } = $activeSlider.data('state'); const $carouselContentElement = $('[data-carousel-content-change-message]', $parentContainer); const carouselContentAnnounceMessage = updateTextWithLiveData(context.carouselContentAnnounceMessage, (activeSlideIdx + 1), slidesQuantity); $carouselContentElement.text(carouselContentAnnounceMessage); }; -export const onSlickCarouselChange = (e, carousel, context) => { +export const onSlickCarouselChange = (e, carouselObj, context) => { const { $dots, $slider, $prevArrow, $nextArrow, - } = carousel; + options: { infinite }, + } = carouselObj; - const { activeSlideIdx, slidesQuantity } = extractSlidesDetails(carousel); + const { activeSlideIdx, slidesQuantity } = $slider.data('state') || getActiveSlideIdxAndSlidesQuantity(carouselObj); dotsSetup($dots, activeSlideIdx, slidesQuantity, context); - arrowAriaLabling($prevArrow, $nextArrow, activeSlideIdx, slidesQuantity, context.carouselArrowAndDotAriaLabel); - setTabindexes($slider.find('.slick-slide')); - tooltipSetup($prevArrow, $nextArrow, $dots); - activatePlayPauseButton(carousel, slidesQuantity, context); + arrowAriaLabling($prevArrow, $nextArrow, activeSlideIdx, slidesQuantity, infinite, context.carouselArrowAndDotAriaLabel); + analizeSlides($slider.find('.slick-slide')); + refreshFocus($prevArrow, $nextArrow, $dots, $slider, activeSlideIdx, slidesQuantity, infinite); + + $slider.data('state', null); }; export default function (context) { $('[data-slick]').each((idx, carousel) => { // getting element using find to pass jest test const $carousel = $(document).find(carousel); + + $carousel.on('init breakpoint swipe', setCarouselState); + $carousel.on('click', '.slick-arrow, .slick-dots', setCarouselState); + + $carousel.on('init breakpoint', (e, carouselObj) => activatePlayPauseButton(e, carouselObj, context)); $carousel.on('init afterChange', (e, carouselObj) => onSlickCarouselChange(e, carouselObj, context)); $carousel.on('click', '.slick-arrow, .slick-dots', $carousel, e => onUserCarouselChange(e, context)); $carousel.on('swipe', (e, carouselObj) => onUserCarouselChange(e, context, carouselObj.$slider)); @@ -65,7 +64,7 @@ export default function (context) { if ($carousel.hasClass('heroCarousel')) { $carousel.on('init afterChange', handleImageLoad); $carousel.on('swipe', handleImageAspectRatio); - $carousel.on('click', '.slick-arrow, .slick-dots', $carousel, handleImageAspectRatio); + $carousel.on('click', '.slick-arrow, .slick-dots', handleImageAspectRatio); // Alternative image styling for IE, which doesn't support objectfit if (typeof document.documentElement.style.objectFit === 'undefined') { diff --git a/assets/js/theme/common/carousel/utils/activatePlayPauseButton.js b/assets/js/theme/common/carousel/utils/activatePlayPauseButton.js index 7405369771..71f4d8be5e 100644 --- a/assets/js/theme/common/carousel/utils/activatePlayPauseButton.js +++ b/assets/js/theme/common/carousel/utils/activatePlayPauseButton.js @@ -2,18 +2,7 @@ import { throttle } from 'lodash'; const PLAY_ACTION = 'slickPlay'; const PAUSE_ACTION = 'slickPause'; -const IS_ACTIVATED_DATA_ATTR = 'is-activated'; - -export default (carousel, slidesQuantity, context) => { - const { $slider, $dots, speed } = carousel; - const $playPauseButton = $slider.find('[data-play-pause-button]'); - - if ($playPauseButton.length === 0) return; - - $playPauseButton.css('display', slidesQuantity < 2 ? 'none' : 'block'); - - if ($playPauseButton.data(IS_ACTIVATED_DATA_ATTR)) return; - +const updateButtonLabels = (context) => { const { carouselPlayPauseButtonPlay, carouselPlayPauseButtonPause, @@ -21,30 +10,43 @@ export default (carousel, slidesQuantity, context) => { carouselPlayPauseButtonAriaPause, } = context; - const updateLabels = action => { - $playPauseButton + return ($button, action) => { + $button .text(action === PLAY_ACTION ? carouselPlayPauseButtonPause : carouselPlayPauseButtonPlay) .attr('aria-label', action === PLAY_ACTION ? carouselPlayPauseButtonAriaPause : carouselPlayPauseButtonAriaPlay); }; +}; +let updateButtonLabelsWithContext; - const onPlayPauseClick = () => { - const action = carousel.paused ? PLAY_ACTION : PAUSE_ACTION; +export default (e, carouselObj, context) => { + const { $slider, $dots, options: { speed } } = carouselObj; + const $playPauseButton = $slider.find('[data-play-pause-button]'); - $slider.slick(action); - updateLabels(action); - }; + if ($playPauseButton.length === 0) return; // for correct carousel controls focus order if ($dots) { $playPauseButton.insertBefore($dots); } else $slider.append($playPauseButton); - $playPauseButton.on('click', throttle(onPlayPauseClick, speed, { trailing: false })); - $playPauseButton.data(IS_ACTIVATED_DATA_ATTR, true); + const { slidesQuantity } = $slider.data('state'); + $playPauseButton.css('display', slidesQuantity > 1 ? 'block' : 'none'); - if (carousel.breakpoints.length) { - $slider.on('breakpoint', () => updateLabels(PLAY_ACTION)); + if (e.type === 'init') updateButtonLabelsWithContext = updateButtonLabels(context); + + if (e.type === 'breakpoint') { + updateButtonLabelsWithContext($playPauseButton, PLAY_ACTION); + return; } + + const onPlayPauseClick = () => { + const action = carouselObj.paused ? PLAY_ACTION : PAUSE_ACTION; + + $slider.slick(action); + updateButtonLabelsWithContext($playPauseButton, action); + }; + + $playPauseButton.on('click', throttle(onPlayPauseClick, speed, { trailing: false })); }; diff --git a/assets/js/theme/common/carousel/utils/analizeSlides.js b/assets/js/theme/common/carousel/utils/analizeSlides.js new file mode 100644 index 0000000000..7b1d38c57d --- /dev/null +++ b/assets/js/theme/common/carousel/utils/analizeSlides.js @@ -0,0 +1,14 @@ +import { FOCUSABLE_ELEMENTS_SELECTOR } from '../constants'; + +export default ($slides) => { + $slides.each((idx, slide) => { + const $slide = $(slide); + const tabIndex = $slide.hasClass('slick-active') ? 0 : -1; + + if ($slide.is(FOCUSABLE_ELEMENTS_SELECTOR)) $slide.attr('tabindex', tabIndex); + + $slide.find(FOCUSABLE_ELEMENTS_SELECTOR).each((index, child) => { + $(child).attr('tabindex', tabIndex); + }); + }); +}; diff --git a/assets/js/theme/common/carousel/utils/arrowAriaLabling.js b/assets/js/theme/common/carousel/utils/arrowAriaLabling.js index 1751262d1d..dc96c2b77a 100644 --- a/assets/js/theme/common/carousel/utils/arrowAriaLabling.js +++ b/assets/js/theme/common/carousel/utils/arrowAriaLabling.js @@ -1,6 +1,7 @@ import updateTextWithLiveData from './updateTextWithLiveData'; +import tooltipSetup from './tooltipSetup'; -export default ($prevArrow, $nextArrow, activeSlideIdx, slidesQuantity, ariaLabel) => { +export default ($prevArrow, $nextArrow, activeSlideIdx, slidesQuantity, isInfinite, ariaLabel) => { if (slidesQuantity < 2 || !$prevArrow || !$nextArrow) return; const activeSlideNumber = activeSlideIdx + 1; @@ -8,10 +9,18 @@ export default ($prevArrow, $nextArrow, activeSlideIdx, slidesQuantity, ariaLabe const prevSlideNumber = activeSlideIdx === 0 ? slidesQuantity : activeSlideNumber - 1; const arrowLeftText = updateTextWithLiveData(ariaLabel, prevSlideNumber, slidesQuantity); - $prevArrow.attr('aria-label', arrowLeftText); + $prevArrow.attr({ + 'aria-label': arrowLeftText, + tabindex: !isInfinite && activeSlideIdx === 0 ? -1 : 0, + }); + tooltipSetup($prevArrow); const nextSlideNumber = activeSlideIdx === slidesQuantity - 1 ? 1 : activeSlideNumber + 1; const arrowRightText = updateTextWithLiveData(ariaLabel, nextSlideNumber, slidesQuantity); - $nextArrow.attr('aria-label', arrowRightText); + $nextArrow.attr({ + 'aria-label': arrowRightText, + tabindex: !isInfinite && activeSlideIdx === slidesQuantity - 1 ? -1 : 0, + }); + tooltipSetup($nextArrow); }; diff --git a/assets/js/theme/common/carousel/utils/dotsSetup.js b/assets/js/theme/common/carousel/utils/dotsSetup.js index 9db5927d7d..109f1847e5 100644 --- a/assets/js/theme/common/carousel/utils/dotsSetup.js +++ b/assets/js/theme/common/carousel/utils/dotsSetup.js @@ -1,4 +1,5 @@ import updateTextWithLiveData from './updateTextWithLiveData'; +import tooltipSetup from './tooltipSetup'; export default ($dots, activeSlideIdx, slidesQuantity, { carouselArrowAndDotAriaLabel, carouselActiveDotAriaLabel }) => { if (!$dots) return; @@ -14,7 +15,8 @@ export default ($dots, activeSlideIdx, slidesQuantity, { carouselArrowAndDotAria const dotLabelText = updateTextWithLiveData(carouselArrowAndDotAriaLabel, idx + 1, slidesQuantity); const dotSlideStatusText = idx === activeSlideIdx ? `, ${carouselActiveDotAriaLabel}` : ''; const dotAriaLabel = `${dotLabelText}${dotSlideStatusText}`; + const $dotButton = $(dot).find('[data-carousel-dot]'); - $(dot).find('[data-carousel-dot]').attr('aria-label', dotAriaLabel); + tooltipSetup($dotButton.attr('aria-label', dotAriaLabel)); }); }; diff --git a/assets/js/theme/common/carousel/utils/getActiveSlideIdxAndSlidesQuantity.js b/assets/js/theme/common/carousel/utils/getActiveSlideIdxAndSlidesQuantity.js index 352a82dc80..83f1cccef2 100644 --- a/assets/js/theme/common/carousel/utils/getActiveSlideIdxAndSlidesQuantity.js +++ b/assets/js/theme/common/carousel/utils/getActiveSlideIdxAndSlidesQuantity.js @@ -1,4 +1,4 @@ -export default (slideCount, slidesToShow, slidesToScroll, $slides) => { +export default ({ slideCount, $slides, options: { slidesToShow, slidesToScroll } }) => { const lastVisibleIdx = $slides.get().reduce((acc, curr, idx) => { if ($(curr).hasClass('slick-active')) return idx; return acc; diff --git a/assets/js/theme/common/carousel/utils/getActiveSlideInfo.js b/assets/js/theme/common/carousel/utils/getActiveSlideInfo.js index c5b67c770e..3cdf46b7df 100644 --- a/assets/js/theme/common/carousel/utils/getActiveSlideInfo.js +++ b/assets/js/theme/common/carousel/utils/getActiveSlideInfo.js @@ -5,16 +5,12 @@ export default ({ $slider }, isAnalyzedDataAttr) => { if (isAnalyzedSlide) return { isAnalyzedSlide }; const $activeSlideImg = $activeSlide.find('.heroCarousel-image'); - - const attrsObj = { - src: $activeSlideImg.attr('src'), - srcset: $activeSlideImg.attr('srcset'), - sizes: $activeSlideImg.attr('sizes'), - }; + const activeSlideImgNode = $activeSlideImg[0]; return { - attrsObj, $slider, $activeSlide, + $activeSlideImg, + activeSlideImgNode, }; }; diff --git a/assets/js/theme/common/carousel/utils/handleImageAspectRatio.js b/assets/js/theme/common/carousel/utils/handleImageAspectRatio.js index ef163e433e..f10ab2cdd6 100644 --- a/assets/js/theme/common/carousel/utils/handleImageAspectRatio.js +++ b/assets/js/theme/common/carousel/utils/handleImageAspectRatio.js @@ -6,7 +6,7 @@ const IMAGE_CLASSES = { }; const IS_ANALYZED_DATA_ATTR = 'image-ratio-analyzed'; -const defineClass = (imageAspectRatio) => { +const defineAspectRatioClass = (imageAspectRatio) => { switch (true) { case imageAspectRatio > 0.8 && imageAspectRatio <= 1.2: return IMAGE_CLASSES.square; @@ -17,13 +17,21 @@ const defineClass = (imageAspectRatio) => { } }; -export default ({ delegateTarget }, carousel) => { +const setAspectRatioClass = (imageNode, $slides) => { + if (imageNode.naturalHeight <= 1) return; + + const imageAspectRatio = imageNode.naturalHeight / imageNode.naturalWidth; + $slides.each((idx, slide) => $(slide).addClass(defineAspectRatioClass(imageAspectRatio))); +}; + +export default ({ delegateTarget }, carouselObj) => { const { isAnalyzedSlide, - attrsObj, $slider, $activeSlide, - } = getActiveSlideInfo(carousel || delegateTarget.slick, IS_ANALYZED_DATA_ATTR); + $activeSlideImg, + activeSlideImgNode, + } = getActiveSlideInfo(carouselObj || delegateTarget.slick, IS_ANALYZED_DATA_ATTR); if (isAnalyzedSlide) return; @@ -32,15 +40,12 @@ export default ({ delegateTarget }, carousel) => { if ($activeSlide.find('.heroCarousel-content').length) return; - $('') - .on('load', function getImageSizes() { - const imageHeight = this.height; - const imageWidth = this.width; - - if (imageHeight < 2 || imageWidth < 2) return; - - const imageAspectRatio = imageHeight / imageWidth; - $activeSlideAndClones.each((idx, slide) => $(slide).addClass(defineClass(imageAspectRatio))); - }) - .attr(attrsObj); + if (activeSlideImgNode.complete) { + if (activeSlideImgNode.naturalHeight === 1) { + // only base64 image from srcset was loaded + $activeSlideImg.on('load', () => setAspectRatioClass(activeSlideImgNode, $activeSlideAndClones)); + } else if (activeSlideImgNode.naturalHeight > 1) { + setAspectRatioClass(activeSlideImgNode, $activeSlideAndClones); + } + } else $activeSlideImg.on('load', () => setAspectRatioClass(activeSlideImgNode, $activeSlideAndClones)); }; diff --git a/assets/js/theme/common/carousel/utils/handleImageLoad.js b/assets/js/theme/common/carousel/utils/handleImageLoad.js index 66572db108..9a9f5383a8 100644 --- a/assets/js/theme/common/carousel/utils/handleImageLoad.js +++ b/assets/js/theme/common/carousel/utils/handleImageLoad.js @@ -1,20 +1,47 @@ +import { isBrowserIE } from '../../utils/ie-helpers'; import getActiveSlideInfo from './getActiveSlideInfo'; const IMAGE_ERROR_CLASS = 'is-image-error'; const IS_ANALYZED_DATA_ATTR = 'image-load-analyzed'; -export default (e, carousel) => { +const generateImage = ($slide, $image) => { + $('') + .on('error', () => $slide.addClass(IMAGE_ERROR_CLASS)) + .attr('src', $image.attr('src')); +}; + +export default (e, carouselObj) => { const { isAnalyzedSlide, - attrsObj, $activeSlide, - } = getActiveSlideInfo(carousel, IS_ANALYZED_DATA_ATTR); + $activeSlideImg, + activeSlideImgNode, + } = getActiveSlideInfo(carouselObj, IS_ANALYZED_DATA_ATTR); if (isAnalyzedSlide) return; $activeSlide.data(IS_ANALYZED_DATA_ATTR, true); - $('') - .on('error', () => $activeSlide.addClass(IMAGE_ERROR_CLASS)) - .attr(attrsObj); + if (activeSlideImgNode.complete) { + if (activeSlideImgNode.naturalHeight === 0) { + $activeSlide.addClass(IMAGE_ERROR_CLASS); + } else if (activeSlideImgNode.naturalHeight === 1) { + // only base64 image from srcset was loaded + $activeSlideImg.on('error', () => $activeSlide.addClass(IMAGE_ERROR_CLASS)); + } + + return; + } + + if (!$activeSlideImg.attr('src')) { + $activeSlide.addClass(IMAGE_ERROR_CLASS); + return; + } + + if (isBrowserIE) { + generateImage($activeSlide, $activeSlideImg); + return; + } + + $activeSlideImg.on('error', () => $activeSlide.addClass(IMAGE_ERROR_CLASS)); }; diff --git a/assets/js/theme/common/carousel/utils/index.js b/assets/js/theme/common/carousel/utils/index.js index 3e7e2dd0a0..f6ad26c659 100644 --- a/assets/js/theme/common/carousel/utils/index.js +++ b/assets/js/theme/common/carousel/utils/index.js @@ -1,9 +1,9 @@ export { default as activatePlayPauseButton } from './activatePlayPauseButton'; +export { default as analizeSlides } from './analizeSlides'; export { default as arrowAriaLabling } from './arrowAriaLabling'; export { default as dotsSetup } from './dotsSetup'; export { default as getActiveSlideIdxAndSlidesQuantity } from './getActiveSlideIdxAndSlidesQuantity'; export { default as handleImageAspectRatio } from './handleImageAspectRatio'; export { default as handleImageLoad } from './handleImageLoad'; -export { default as setTabindexes } from './setTabindexes'; -export { default as tooltipSetup } from './tooltipSetup'; +export { default as refreshFocus } from './refreshFocus'; export { default as updateTextWithLiveData } from './updateTextWithLiveData'; diff --git a/assets/js/theme/common/carousel/utils/refreshFocus.js b/assets/js/theme/common/carousel/utils/refreshFocus.js new file mode 100644 index 0000000000..dad85f3d56 --- /dev/null +++ b/assets/js/theme/common/carousel/utils/refreshFocus.js @@ -0,0 +1,20 @@ +import { FOCUSABLE_ELEMENTS_SELECTOR } from '../constants'; + +export default ($prevArrow, $nextArrow, $dots, $slider, activeSlideIdx, slidesQuantity, isInfinite) => { + if (isInfinite || !$prevArrow || !$nextArrow) return; + + if (activeSlideIdx === 0 && $prevArrow.is(':focus')) { + $nextArrow.focus(); + } else if (activeSlideIdx === slidesQuantity - 1 && $nextArrow.is(':focus')) { + if ($dots) { + $dots.children().first().find('[data-carousel-dot]').focus(); + return; + } + + const $firstActiveSlide = $slider.find('.slick-active').first(); + + if ($firstActiveSlide.is(FOCUSABLE_ELEMENTS_SELECTOR)) { + $firstActiveSlide.focus(); + } else $firstActiveSlide.find(FOCUSABLE_ELEMENTS_SELECTOR).first().focus(); + } +}; diff --git a/assets/js/theme/common/carousel/utils/tooltipSetup.js b/assets/js/theme/common/carousel/utils/tooltipSetup.js index da4af37856..c2a6003ba0 100644 --- a/assets/js/theme/common/carousel/utils/tooltipSetup.js +++ b/assets/js/theme/common/carousel/utils/tooltipSetup.js @@ -2,7 +2,7 @@ const TOOLTIP_DATA_SELECTOR = 'data-carousel-tooltip'; const TOOLTIP_CLASS = 'carousel-tooltip'; const TOOLTIP_NODE = ``; -const setupTooltipAriaLabel = ($node) => { +export default ($node) => { const $existedTooltip = $node.find(`[${TOOLTIP_DATA_SELECTOR}]`); if ($existedTooltip.length) { $existedTooltip.attr('aria-label', $node.attr('aria-label')); @@ -11,21 +11,3 @@ const setupTooltipAriaLabel = ($node) => { $node.append($tooltip); } }; - -const setupArrowTooltips = (...arrowNodes) => { - arrowNodes.forEach($arrow => setupTooltipAriaLabel($arrow)); -}; - -const setupDotTooltips = ($dots) => { - $dots.children().each((idx, dot) => setupTooltipAriaLabel($('[data-carousel-dot]', dot))); -}; - -export default ($prevArrow, $nextArrow, $dots) => { - if ($prevArrow && $nextArrow) { - setupArrowTooltips($prevArrow, $nextArrow); - } - - if ($dots) { - setupDotTooltips($dots); - } -}; diff --git a/assets/js/theme/common/faceted-search.js b/assets/js/theme/common/faceted-search.js index 78d2b18b4c..b1aa534179 100644 --- a/assets/js/theme/common/faceted-search.js +++ b/assets/js/theme/common/faceted-search.js @@ -2,7 +2,7 @@ import { hooks, api } from '@bigcommerce/stencil-utils'; import _ from 'lodash'; import Url from 'url'; import urlUtils from './utils/url-utils'; -import modalFactory, { ModalEvents } from '../global/modal'; +import modalFactory from '../global/modal'; import collapsibleFactory from './collapsible'; import { Validators } from './utils/form-utils'; import nod from './nod'; diff --git a/assets/js/theme/common/models/forms.js b/assets/js/theme/common/models/forms.js index c4870e68dd..ddb7dfc846 100644 --- a/assets/js/theme/common/models/forms.js +++ b/assets/js/theme/common/models/forms.js @@ -1,6 +1,6 @@ const forms = { email(value) { - const re = /^.+@.+\..+/; + const re = /^\S+@\S+\.\S+/; return re.test(value); }, diff --git a/assets/js/theme/common/product-details.js b/assets/js/theme/common/product-details.js index e9f3174fec..c475f6b66e 100644 --- a/assets/js/theme/common/product-details.js +++ b/assets/js/theme/common/product-details.js @@ -3,7 +3,7 @@ import ProductDetailsBase, { optionChangeDecorator } from './product-details-bas import 'foundation-sites/js/foundation/foundation'; import 'foundation-sites/js/foundation/foundation.reveal'; import ImageGallery from '../product/image-gallery'; -import modalFactory, { showAlertModal } from '../global/modal'; +import modalFactory, { alertModal, showAlertModal } from '../global/modal'; import { isEmpty, isPlainObject } from 'lodash'; import { normalizeFormData } from './utils/api'; import { isBrowserIE, convertIntoArray } from './utils/ie-helpers'; @@ -18,20 +18,44 @@ export default class ProductDetails extends ProductDetailsBase { this.imageGallery.init(); this.listenQuantityChange(); this.$swatchOptionMessage = $('.swatch-option-message'); - this.swatchOptionMessageInitText = this.$swatchOptionMessage.text(); + this.swatchInitMessageStorage = {}; + this.swatchGroupIdList = $('[id^="swatchGroup"]').map((_, group) => $(group).attr('id')); + this.storeInitMessagesForSwatches(); const $form = $('form[data-cart-item-add]', $scope); const $productOptionsElement = $('[data-product-option-change]', $form); const hasOptions = $productOptionsElement.html().trim().length; const hasDefaultOptions = $productOptionsElement.find('[data-default]').length; const $productSwatchGroup = $('[id*="attribute_swatch"]', $form); + const $productSwatchLabels = $('.form-option-swatch', $form); + const placeSwatchLabelImage = (_, label) => { + const $optionImage = $('.form-option-expanded', $(label)); + const optionImageWidth = $optionImage.outerWidth(); + const extendedOptionImageOffsetLeft = 55; + const { right } = label.getBoundingClientRect(); + const emptySpaceToScreenRightBorder = window.screen.width - right; + const shiftValue = optionImageWidth - emptySpaceToScreenRightBorder; + + if (emptySpaceToScreenRightBorder < (optionImageWidth + extendedOptionImageOffsetLeft)) { + $optionImage.css('left', `${shiftValue > 0 ? -shiftValue : shiftValue}px`); + } + }; + + $(window).on('load', () => $.each($productSwatchLabels, placeSwatchLabelImage)); if (context.showSwatchNames) { this.$swatchOptionMessage.removeClass('u-hidden'); - $productSwatchGroup.on('change', ({ target }) => this.showSwatchNameOnOption($(target))); + + $productSwatchGroup.on('change', ({ target }) => { + const swatchGroupElement = target.parentNode.parentNode; + + this.showSwatchNameOnOption($(target), $(swatchGroupElement)); + }); $.each($productSwatchGroup, (_, element) => { - if ($(element).is(':checked')) this.showSwatchNameOnOption($(element)); + const swatchGroupElement = element.parentNode.parentNode; + + if ($(element).is(':checked')) this.showSwatchNameOnOption($(element), $(swatchGroupElement)); }); } @@ -61,6 +85,16 @@ export default class ProductDetails extends ProductDetailsBase { this.previewModal = modalFactory('#previewModal')[0]; } + storeInitMessagesForSwatches() { + if (this.swatchGroupIdList.length && isEmpty(this.swatchInitMessageStorage)) { + this.swatchGroupIdList.each((_, swatchGroupId) => { + if (!this.swatchInitMessageStorage[swatchGroupId]) { + this.swatchInitMessageStorage[swatchGroupId] = $(`#${swatchGroupId} ~ .swatch-option-message`).text().trim(); + } + }); + } + } + setProductVariant() { const unsatisfiedRequiredFields = []; const options = []; @@ -196,6 +230,11 @@ export default class ProductDetails extends ProductDetailsBase { this.updateProductAttributes(productAttributesData); this.updateView(productAttributesData, productAttributesContent); bannerUtils.dispatchProductBannerEvent(productAttributesData); + + if (!this.checkIsQuickViewChild($form)) { + const $context = $form.parents('.productView').find('.productView-info'); + modalFactory('[data-reveal]', { $context }); + } }); } @@ -203,12 +242,14 @@ export default class ProductDetails extends ProductDetailsBase { * if this setting is enabled in Page Builder * show name for swatch option */ - showSwatchNameOnOption($swatch) { + showSwatchNameOnOption($swatch, $swatchGroup) { const swatchName = $swatch.attr('aria-label'); + const activeSwatchGroupId = $swatchGroup.attr('aria-labelledby'); + const $swatchOptionMessage = $(`#${activeSwatchGroupId} ~ .swatch-option-message`); - $('[data-product-attribute="swatch"] [data-option-value]').text(swatchName); - this.$swatchOptionMessage.text(`${this.swatchOptionMessageInitText} ${swatchName}`); - this.setLiveRegionAttributes(this.$swatchOptionMessage, 'status', 'assertive'); + $('[data-option-value]', $swatchGroup).text(swatchName); + $swatchOptionMessage.text(`${this.swatchInitMessageStorage[activeSwatchGroupId]} ${swatchName}`); + this.setLiveRegionAttributes($swatchOptionMessage, 'status', 'assertive'); } setLiveRegionAttributes($element, roleType, ariaLiveStatus) { @@ -218,6 +259,10 @@ export default class ProductDetails extends ProductDetailsBase { }); } + checkIsQuickViewChild($element) { + return !!$element.parents('.quickView').length; + } + showProductImage(image) { if (isPlainObject(image)) { const zoomImageUrl = utils.tools.imageSrcset.getSrcset( @@ -354,6 +399,10 @@ export default class ProductDetails extends ProductDetailsBase { const tmp = document.createElement('DIV'); tmp.innerHTML = errorMessage; + if (!this.checkIsQuickViewChild($addToCartBtn)) { + alertModal().$preModalFocusedEl = $addToCartBtn; + } + return showAlertModal(tmp.textContent || tmp.innerText); } @@ -361,8 +410,15 @@ export default class ProductDetails extends ProductDetailsBase { if (this.previewModal) { this.previewModal.open(); - if ($addToCartBtn.parents('.quickView').length === 0) this.previewModal.$preModalFocusedEl = $addToCartBtn; - this.updateCartContent(this.previewModal, response.data.cart_item.id, () => this.previewModal.setupFocusTrap()); + if (window.ApplePaySession) { + this.previewModal.$modal.addClass('apple-pay-supported'); + } + + if (!this.checkIsQuickViewChild($addToCartBtn)) { + this.previewModal.$preModalFocusedEl = $addToCartBtn; + } + + this.updateCartContent(this.previewModal, response.data.cart_item.id); } else { this.$overlay.show(); // if no modal, redirect to the cart page diff --git a/assets/js/theme/common/utils/ie-helpers.js b/assets/js/theme/common/utils/ie-helpers.js index c65b0c1275..cde421dc48 100644 --- a/assets/js/theme/common/utils/ie-helpers.js +++ b/assets/js/theme/common/utils/ie-helpers.js @@ -1,3 +1,3 @@ -export const isBrowserIE = navigator.userAgent.includes('Trident'); +export const isBrowserIE = !!document.documentMode; export const convertIntoArray = collection => Array.prototype.slice.call(collection); diff --git a/assets/js/theme/global/cart-preview.js b/assets/js/theme/global/cart-preview.js index 876b9a3981..b6681a6e2e 100644 --- a/assets/js/theme/global/cart-preview.js +++ b/assets/js/theme/global/cart-preview.js @@ -15,6 +15,10 @@ export default function (secureBaseUrl, cartId) { const $body = $('body'); + if (window.ApplePaySession) { + $cartDropdown.addClass('apple-pay-supported'); + } + $body.on('cart-quantity-update', (event, quantity) => { $cart.attr('aria-label', (_, prevValue) => prevValue.replace(/\d+/, quantity)); diff --git a/assets/js/theme/global/modal.js b/assets/js/theme/global/modal.js index 8536397e77..20588bc543 100644 --- a/assets/js/theme/global/modal.js +++ b/assets/js/theme/global/modal.js @@ -17,6 +17,7 @@ export const ModalEvents = { closed: 'closed.fndtn.reveal', open: 'open.fndtn.reveal', opened: 'opened.fndtn.reveal', + loaded: 'loaded.data.custom', }; function getSizeFromModal($modal) { @@ -187,6 +188,7 @@ export class Modal { this.pending = false; this.$content.html($content); + this.$modal.trigger(ModalEvents.loaded); restrainContentHeight(this.$content); foundation(this.$content); @@ -203,6 +205,14 @@ export class Modal { this.focusTrap = focusTrap.createFocusTrap(this.$modal[0], { escapeDeactivates: false, returnFocusOnDeactivate: false, + allowOutsideClick: true, + fallbackFocus: () => { + const fallbackNode = this.$preModalFocusedEl && this.$preModalFocusedEl.length + ? this.$preModalFocusedEl[0] + : $('[data-header-logo-link]')[0]; + + return fallbackNode; + }, }); } @@ -229,6 +239,14 @@ export class Modal { } onModalOpened() { + if (this.pending) { + this.$modal.one(ModalEvents.loaded, () => { + if (this.$modal.hasClass('open')) this.setupFocusTrap(); + }); + } else { + this.setupFocusTrap(); + } + restrainContentHeight(this.$content); } } diff --git a/assets/js/theme/global/quick-view.js b/assets/js/theme/global/quick-view.js index 85b13bcdd7..d4ab963755 100644 --- a/assets/js/theme/global/quick-view.js +++ b/assets/js/theme/global/quick-view.js @@ -4,7 +4,7 @@ import utils from '@bigcommerce/stencil-utils'; import ProductDetails from '../common/product-details'; import { defaultModal } from './modal'; import 'slick-carousel'; -import { onSlickCarouselChange, onUserCarouselChange } from '../common/carousel'; +import { setCarouselState, onSlickCarouselChange, onUserCarouselChange } from '../common/carousel'; export default function (context) { const modal = defaultModal(); @@ -24,15 +24,16 @@ export default function (context) { const $carousel = modal.$content.find('[data-slick]'); if ($carousel.length) { - $carousel.on('init afterChange', (e, carousel) => onSlickCarouselChange(e, carousel, context)); + $carousel.on('init breakpoint swipe', setCarouselState); + $carousel.on('click', '.slick-arrow, .slick-dots', setCarouselState); + + $carousel.on('init afterChange', (e, carouselObj) => onSlickCarouselChange(e, carouselObj, context)); $carousel.on('click', '.slick-arrow, .slick-dots', $carousel, e => onUserCarouselChange(e, context)); $carousel.on('swipe', (e, carouselObj) => onUserCarouselChange(e, context, carouselObj.$slider)); $carousel.slick(); } - modal.setupFocusTrap(); - return new ProductDetails(modal.$content.find('.quickView'), context); }); }); diff --git a/assets/js/theme/search.js b/assets/js/theme/search.js index f022231cdb..8467de01e5 100644 --- a/assets/js/theme/search.js +++ b/assets/js/theme/search.js @@ -204,9 +204,15 @@ export default class Search extends CatalogPage { } }); - setTimeout(() => { - $('[data-search-aria-message]').removeClass('u-hidden'); - }, 100); + const $searchResultsMessage = $(`

${this.context.searchResultsCount}

`) + .prependTo('body'); + + setTimeout(() => $searchResultsMessage.focus(), 100); } loadTreeNodes(node, cb) { diff --git a/assets/scss/common/_focus-tooltip.scss b/assets/scss/common/_focus-tooltip.scss index 9d1bd3ccbf..7a7fed7052 100644 --- a/assets/scss/common/_focus-tooltip.scss +++ b/assets/scss/common/_focus-tooltip.scss @@ -6,14 +6,14 @@ top: 50%; border-width: remCalc(10px); border-style: solid; - border-color: transparent transparent $adminBar-tooltip-bg-backgroundColor transparent; + border-color: transparent transparent $focusTooltip-backgroundColor transparent; } &:after { content: attr($attr); padding: remCalc(4px) remCalc(6px); - background-color: $adminBar-tooltip-bg-backgroundColor; - color: white; + background-color: $focusTooltip-backgroundColor; + color: $focusTooltip-textColor; position: absolute; font-size: 1rem; white-space: nowrap; diff --git a/assets/scss/components/stencil/applePay/_applePay.scss b/assets/scss/components/stencil/applePay/_applePay.scss index dbaf8a4a8c..c931dd0d63 100644 --- a/assets/scss/components/stencil/applePay/_applePay.scss +++ b/assets/scss/components/stencil/applePay/_applePay.scss @@ -25,23 +25,14 @@ } } -.cart-additionalCheckoutButtons { - .apple-pay-checkout-button { - margin-top: spacing("half"); - } -} - .apple-pay-supported { .apple-pay-checkout-button { display: block; float: right; } -} -.previewCartCheckout { - .apple-pay-checkout-button { + & .previewCartCheckout .apple-pay-checkout-button { display: inline-block; float: none; - margin-top: spacing("half"); } } diff --git a/assets/scss/components/stencil/cart/_cart.scss b/assets/scss/components/stencil/cart/_cart.scss index a119cf829b..eaca20cdcc 100644 --- a/assets/scss/components/stencil/cart/_cart.scss +++ b/assets/scss/components/stencil/cart/_cart.scss @@ -43,18 +43,6 @@ $card-preview-zoom-bottom-offset: 6rem; float: right; } } - - .CheckoutButton { - margin-bottom: spacing("base"); - - &:first-child { - margin-top: spacing("single"); - } - - &:last-child { - margin-bottom: spacing("single"); - } - } } // Cart layout @@ -557,7 +545,8 @@ $card-preview-zoom-bottom-offset: 6rem; .previewCart-additionalCheckoutButtons { @extend %additionalCheckoutButtons; - padding-right: 1.5rem; + padding-right: spacing('single'); + padding-bottom: spacing('single'); } // Cart Preview @@ -608,7 +597,6 @@ $card-preview-zoom-bottom-offset: 6rem; } @include lazy-loaded-padding('productthumb_size'); - &:after { @include breakpoint("xxsmall") { padding-bottom: 75%; diff --git a/assets/scss/components/stencil/heroCarousel/_heroCarousel.scss b/assets/scss/components/stencil/heroCarousel/_heroCarousel.scss index 296b8acd33..99c9836287 100644 --- a/assets/scss/components/stencil/heroCarousel/_heroCarousel.scss +++ b/assets/scss/components/stencil/heroCarousel/_heroCarousel.scss @@ -34,6 +34,15 @@ } } + // for IE + @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) { + opacity: 0; + + &.slick-initialized { + opacity: 1; + } + } + &:not(.slick-initialized) :not(.heroCarousel-slide--first).heroCarousel-slide { display: none; } @@ -97,6 +106,34 @@ background-size: contain; } } + + .slick-slide { + &.is-square-image-type { + .heroCarousel-image-wrapper { + height: 100vw; + } + } + + &.is-vertical-image-type { + .heroCarousel-image-wrapper { + height: 110vw; + } + } + + &.is-square-image-type, + &.is-vertical-image-type { + .heroCarousel-image-wrapper { + @include breakpoint("small") { + height: 56.25vw; + } + } + } + + &.is-image-error { + background: url("../img/hero-carousel-image-load-error.svg") center center no-repeat; + background-size: contain; + } + } } .heroCarousel-slide { diff --git a/assets/scss/components/stencil/previewCart/_previewCart.scss b/assets/scss/components/stencil/previewCart/_previewCart.scss index e8967df692..52bb04ca2d 100644 --- a/assets/scss/components/stencil/previewCart/_previewCart.scss +++ b/assets/scss/components/stencil/previewCart/_previewCart.scss @@ -56,10 +56,13 @@ width: 100%; // scss-lint:disable NestingDepth - + .button, + p { margin-top: spacing("half"); } + + &:not(:last-child) { + margin-bottom: spacing("half"); + } } } diff --git a/assets/scss/components/stencil/productView/_productView.scss b/assets/scss/components/stencil/productView/_productView.scss index ce86de333e..ab5242a0d8 100644 --- a/assets/scss/components/stencil/productView/_productView.scss +++ b/assets/scss/components/stencil/productView/_productView.scss @@ -130,6 +130,8 @@ // ----------------------------------------------------------------------------- .productView-details { + padding-bottom: spacing("single") + spacing("third"); + &.productView-details--cartAction { position: fixed; border-top: container("border");; @@ -151,7 +153,6 @@ margin-bottom: 0; padding-bottom: spacing("single") + spacing("third"); } - padding-bottom: spacing("single") + spacing("third"); &.product-options { overflow: hidden; // 1 diff --git a/assets/scss/components/vendor/slick/_slick.scss b/assets/scss/components/vendor/slick/_slick.scss index 2f8e497ab3..5445e4f503 100644 --- a/assets/scss/components/vendor/slick/_slick.scss +++ b/assets/scss/components/vendor/slick/_slick.scss @@ -183,9 +183,6 @@ div.slick-slider { *width: 100%; } -.slick-list { - margin-bottom: 12px; -} // // Carousel tooltips for buttons and bullets diff --git a/assets/scss/components/vendor/sweetalert2/_sweetalert2.scss b/assets/scss/components/vendor/sweetalert2/_sweetalert2.scss index f9ef8ee5c2..9e27d2d56f 100644 --- a/assets/scss/components/vendor/sweetalert2/_sweetalert2.scss +++ b/assets/scss/components/vendor/sweetalert2/_sweetalert2.scss @@ -102,3 +102,7 @@ .swal2-icon { display: flex; } + +.swal2-container { + z-index: 1000; // should be less then foundation modal +} diff --git a/assets/scss/layouts/header/_header.scss b/assets/scss/layouts/header/_header.scss index 33a5cedaea..30eeaa318b 100644 --- a/assets/scss/layouts/header/_header.scss +++ b/assets/scss/layouts/header/_header.scss @@ -185,26 +185,24 @@ } } -// .header-logo-image-container { -// position: relative; -// } +.header-logo-image-container { + position: relative; + width: 100%; -// .header-logo-image-container:after { -// content: ''; -// display: block; -// padding-bottom: remCalc($header-height) - $header-logo-marginVertical * 2; + @include breakpoint("medium") { + min-height: get-height(stencilString('logo_size')); + } +} -// @include breakpoint("medium") { -// padding-bottom: get-height(stencilString('logo_size')); -// } -// } +.header-logo-image-container:after { + content: ''; + display: block; +} .header-logo-image { - @include lazy-loaded-img; + max-height: remCalc($header-height) - $header-logo-marginVertical * 2; + display: block; margin: 0 auto; - top: 10px; - max-height: remCalc($header-height) - $header-logo-marginVertical * 1; - z-index: 50; @include breakpoint("medium") { max-height: none; diff --git a/assets/scss/settings/global/color/_color.scss b/assets/scss/settings/global/color/_color.scss index 6dc9637cfa..c7d0025151 100644 --- a/assets/scss/settings/global/color/_color.scss +++ b/assets/scss/settings/global/color/_color.scss @@ -68,7 +68,8 @@ $color-textLink: stencilColor("color-textLink"); $color-textLink-hover: stencilColor("color-textLink--hover"); $color-textLink-active: stencilColor("color-textLink--active"); -// Site Specific + +// Tooltips // ----------------------------------------------------------------------------- -$color-sitePrimary: stencilColor("color-sitePrimary"); -$color-siteSecondary: stencilColor("color-sitePrimary"); +$focusTooltip-textColor: stencilColor("focusTooltip-textColor"); +$focusTooltip-backgroundColor: stencilColor("focusTooltip-backgroundColor"); diff --git a/config.json b/config.json index c431c8ee18..089f3c2e29 100644 --- a/config.json +++ b/config.json @@ -1,6 +1,6 @@ { "name": "Midwest Nice", - "version": "5.3.0", + "version": "5.5.0", "template_engine": "handlebars_v4", "meta": { "price": 0, @@ -321,12 +321,12 @@ "color_badge_product_sold_out_badges": "#007dc6", "color_text_product_sold_out_badges": "#ffffff", "color_hover_product_sold_out_badges": "#000000", + "focusTooltip-textColor": "#ffffff", + "focusTooltip-backgroundColor": "#313440", "restrict_to_login": false, "swatch_option_size": "22x22", "social_icon_placement_top": false, "social_icon_placement_bottom": "bottom_none", - "geotrust_ssl_common_name": "", - "geotrust_ssl_seal_size": "M", "navigation_design": "simple", "price_ranges": true, "pdp-price-label": "", @@ -343,6 +343,13 @@ "paymentbuttons-paypal-label": "checkout", "paymentbuttons-paypal-tagline": false, "paymentbuttons-paypal-fundingicons": false, + "paymentbanners-homepage-color": "white", + "paymentbanners-homepage-ratio": "8x1", + "paymentbanners-cartpage-text-color": "black", + "paymentbanners-cartpage-logo-position": "left", + "paymentbanners-cartpage-logo-type": "primary", + "paymentbanners-proddetailspage-color": "white", + "paymentbanners-proddetailspage-ratio": "8x1", "supported_card_type_icons": [ "american_express", "diners", @@ -965,7 +972,9 @@ "color_hover_product_sale_badges": "#000000", "color_badge_product_sold_out_badges": "#007dc6", "color_text_product_sold_out_badges": "#ffffff", - "color_hover_product_sold_out_badges": "#000000" + "color_hover_product_sold_out_badges": "#000000", + "focusTooltip-textColor": "#666666", + "focusTooltip-backgroundColor": "#ffffff" } }, { @@ -1173,7 +1182,9 @@ "color_hover_product_sale_badges": "#000000", "color_badge_product_sold_out_badges": "#007dc6", "color_text_product_sold_out_badges": "#ffffff", - "color_hover_product_sold_out_badges": "#000000" + "color_hover_product_sold_out_badges": "#000000", + "focusTooltip-textColor": "#ffffff", + "focusTooltip-backgroundColor": "#313440" } } ] diff --git a/package-lock.json b/package-lock.json index 754da23b7f..27ff0fd046 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "bigcommerce-cornerstone", - "version": "5.3.0", + "version": "5.5.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "bigcommerce-cornerstone", - "version": "5.3.0", + "version": "5.5.0", "license": "MIT", "dependencies": { "@bigcommerce/stencil-utils": "^6.8.1", diff --git a/package.json b/package.json index 7fa1199592..cd941f44d7 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "bigcommerce-cornerstone", "description": "The BigCommerce reference theme for the Stencil platform", - "version": "5.3.0", + "version": "5.5.0", "private": true, "author": "BigCommerce", "license": "MIT", diff --git a/schema.json b/schema.json index 33a8b17586..2e28f87f0c 100644 --- a/schema.json +++ b/schema.json @@ -962,36 +962,6 @@ "label": "i18n.ShowKlarna", "force_reload": true, "id": "show_accept_klarna" - }, - { - "type": "heading", - "content": "i18n.GeoTrustSSL" - }, - { - "type": "paragraph", - "content": "i18n.IfYouvePurchasedAGeoTrust" - }, - { - "type": "text", - "label": "i18n.SSLCommonName", - "force_reload": true, - "id": "geotrust_ssl_common_name" - }, - { - "type": "select", - "label": "i18n.SealSize", - "id": "geotrust_ssl_seal_size", - "options": [ - { - "value": "M", - "label": "i18n.Medium" - }, - { - "value": "S", - "label": "i18n.Small" - } - ], - "force_reload": true } ] }, @@ -3176,5 +3146,199 @@ ] } ] + }, + { + "name": "i18n.PaymentBanners", + "enable": "paymentBanners", + "settings": [ + { + "type": "paragraph", + "content": "i18n.BannersMessaging" + }, + { + "type": "heading", + "content": "i18n.ProductPageBanner" + }, + { + "type": "select", + "label": "i18n.BannerStyleColor", + "id": "paymentbanners-proddetailspage-color", + "force_reload": true, + "options": [ + { + "value": "blue", + "label": "i18n.Blue" + }, + { + "value": "black", + "label": "i18n.Black" + }, + { + "value": "white", + "label": "i18n.White" + }, + { + "value": "white-no-border", + "label": "i18n.White-no-border" + }, + { + "value": "gray", + "label": "i18n.gray" + }, + { + "value": "monochrome", + "label": "i18n.monochrome" + }, + { + "value": "grayscale", + "label": "i18n.grayscale" + } + ] + }, + { + "type": "select", + "label": "i18n.BannerStyleRatio", + "id": "paymentbanners-proddetailspage-ratio", + "force_reload": true, + "options": [ + { + "value": "8x1", + "label": "i18n.8x1" + }, + { + "value": "20x1", + "label": "i18n.20x1" + } + ] + }, + { + "type": "heading", + "content": "i18n.HomePageBanner" + }, + { + "type": "select", + "label": "i18n.BannerStyleColor", + "id": "paymentbanners-homepage-color", + "force_reload": true, + "options": [ + { + "value": "blue", + "label": "i18n.Blue" + }, + { + "value": "black", + "label": "i18n.Black" + }, + { + "value": "white", + "label": "i18n.White" + }, + { + "value": "white-no-border", + "label": "i18n.White-no-border" + }, + { + "value": "gray", + "label": "i18n.gray" + }, + { + "value": "monochrome", + "label": "i18n.monochrome" + }, + { + "value": "grayscale", + "label": "i18n.grayscale" + } + ] + }, + { + "type": "select", + "label": "i18n.BannerStyleRatio", + "id": "paymentbanners-homepage-ratio", + "force_reload": true, + "options": [ + { + "value": "8x1", + "label": "i18n.8x1" + }, + { + "value": "20x1", + "label": "i18n.20x1" + } + ] + }, + { + "type": "heading", + "content": "i18n.CartPageBanner" + }, + { + "type": "select", + "label": "i18n.BannerTextStyleColor", + "id": "paymentbanners-cartpage-text-color", + "force_reload": true, + "options": [ + { + "value": "black", + "label": "i18n.Black" + }, + { + "value": "white", + "label": "i18n.White" + }, + { + "value": "monochrome", + "label": "i18n.monochrome" + }, + { + "value": "grayscale", + "label": "i18n.grayscale" + } + ] + }, + { + "type": "select", + "label": "i18n.BannerStyleLogoPosition", + "id": "paymentbanners-cartpage-logo-position", + "force_reload": true, + "options": [ + { + "value": "left", + "label": "i18n.left" + }, + { + "value": "right", + "label": "i18n.right" + }, + { + "value": "top", + "label": "i18n.top" + } + ] + }, + { + "type": "select", + "label": "i18n.BannerStyleLogoType", + "id": "paymentbanners-cartpage-logo-type", + "force_reload": true, + "options": [ + { + "value": "inline", + "label": "i18n.inline" + }, + { + "value": "primary", + "label": "i18n.primary" + }, + { + "value": "alternative", + "label": "i18n.alternative" + }, + { + "value": "none", + "label": "i18n.none" + } + ] + } + ] } ] diff --git a/schemaTranslations.json b/schemaTranslations.json index 66364f0ba1..fc98a816f1 100644 --- a/schemaTranslations.json +++ b/schemaTranslations.json @@ -866,34 +866,6 @@ "uk": "Показати Klarna", "zh": "显示 Klarna" }, - "i18n.GeoTrustSSL": { - "default": "GeoTrust SSL", - "fr": "SSL GeoTrust", - "it": "GeoTrust SSL", - "uk": "GeoTrust SSL", - "zh": "Geo信任SSL" - }, - "i18n.IfYouvePurchasedAGeoTrust": { - "default": "If you've purchased a GeoTrust SSL from BigCommerce, check your BigCommerce Account Dashboard for the correct Common Name to use here.", - "fr": "Si vous avez acheté un SSL GeoTrust auprès de BigCommerce, consultez le tableau de bord de votre compte BigCommerce pour le nom commun correct à utiliser ici.", - "it": "Sei hai acquistato un SSL GeoTrust da BigCommerce, verifica sulla Dashboard del tuo Account BigCommerce il corretto Nome Comune da utilizzare qui.", - "uk": "Якщо ви придбали GeoTrust SSL у BigCommerce, перевірте на панелі керування облікового запису BigCommerce правильну загальну назву, яку тут можна використовувати.", - "zh": "如果您有在Bigcommerce中购买Geo信任SSL,检查您的Bigcommerce账户的控制面板,获得在这里使用的正确的公共名称。" - }, - "i18n.SSLCommonName": { - "default": "SSL Common Name", - "fr": "Nom commun du SSL", - "it": "Nome Comune SSL", - "uk": "Загальна назва SSL", - "zh": "SSL公共名称" - }, - "i18n.SealSize": { - "default": "Seal size", - "fr": "Taille du sceau", - "it": "Dimensioni sigillo", - "uk": "Розмір печатки", - "zh": "标志尺寸" - }, "i18n.Medium": { "default": "Medium", "fr": "Moyen", @@ -2047,5 +2019,74 @@ }, "i18n.CheckoutPayPalButton": { "default": "Checkout PayPal Button" + }, + "i18n.ProductPageBanner": { + "default": "Product page banner" + }, + "i18n.BannerStyleColor": { + "default": "Banner style color" + }, + "i18n.White-no-border": { + "default": "White no border" + }, + "i18n.gray": { + "default": "Gray" + }, + "i18n.monochrome": { + "default": "Monochrome" + }, + "i18n.grayscale": { + "default": "Grayscale" + }, + "i18n.BannerStyleRatio": { + "default": "Banner style ratio" + }, + "i18n.8x1": { + "default": "8x1" + }, + "i18n.20x1": { + "default": "20x1" + }, + "i18n.HomePageBanner": { + "default": "Home page banner" + }, + "i18n.BannerTextStyleColor": { + "default": "Banner text style color" + }, + "i18n.BannerStyleLogoPosition": { + "default": "Banner style logo position" + }, + "i18n.left": { + "default": "Left" + }, + "i18n.right": { + "default": "Right" + }, + "i18n.top": { + "default": "Top" + }, + "i18n.BannerStyleLogoType": { + "default": "Banner style logo type" + }, + "i18n.inline": { + "default": "Inline" + }, + "i18n.alternative": { + "default": "Alternative" + }, + "i18n.none": { + "default": "None" + }, + "i18n.PaymentBanners": { + "default": "Payment Banners" + }, + "i18n.CartPageBanner": { + "default": "Cart page banner" + }, + "i18n.primary": { + "default": "Primary" + }, + "i18n.BannersMessaging": { + "default": "Please note that in order for the changes to apply, you need navigate to the PayPal Settings in BC Control Panel, disable an appropriate messaging banner(s), click \"Save\" button, enable the banner again and click \"Save\" button again" } } diff --git a/templates/components/amp/products/product-view-details.html b/templates/components/amp/products/product-view-details.html index 1a9cf6956e..3330cbb7e6 100644 --- a/templates/components/amp/products/product-view-details.html +++ b/templates/components/amp/products/product-view-details.html @@ -2,7 +2,7 @@

{{product.title}}

{{#if product.brand }} -

+

{{/if}} diff --git a/templates/components/amp/products/reviews.html b/templates/components/amp/products/reviews.html index 253e534592..a170886893 100644 --- a/templates/components/amp/products/reviews.html +++ b/templates/components/amp/products/reviews.html @@ -7,9 +7,9 @@

    {{#each reviews.list}}
  • -
    +
    - + {{> components/amp/products/ratings rating=rating}} {{ rating }} diff --git a/templates/components/common/body.html b/templates/components/common/body.html index 37249490b2..a292afad97 100644 --- a/templates/components/common/body.html +++ b/templates/components/common/body.html @@ -1,4 +1,4 @@ -
    +
    {{#block "hero"}} {{/block}}
    {{#block "page"}} {{/block}} diff --git a/templates/components/common/breadcrumbs.html b/templates/components/common/breadcrumbs.html index 397117e31d..9586a1ebbe 100644 --- a/templates/components/common/breadcrumbs.html +++ b/templates/components/common/breadcrumbs.html @@ -1,8 +1,8 @@

{{> components/common/payment-icons}} - {{#if theme_settings.geotrust_ssl_common_name}} - + {{#if settings.paypal_commerce_credit_message}} + {{/if}} {{#if settings.paypal_commerce_credit_message}} {{/if}}
- \ No newline at end of file + {{{region name="ssl_site_seal--global"}}} + diff --git a/templates/components/common/share.html b/templates/components/common/share.html index dee1c94340..1244506c74 100644 --- a/templates/components/common/share.html +++ b/templates/components/common/share.html @@ -1,57 +1,90 @@ {{#if settings.add_this.buttons}} -
+ {{assignVar 'encodedUrl' (encodeURI url)}} + {{assignVar 'encodedTitle' (encodeURI head.title)}} +
- -
{{/if}} {{#if settings.facebook_like_button.enabled}} diff --git a/templates/components/common/store-logo.html b/templates/components/common/store-logo.html index 737fd43ce6..82a4f65d8b 100644 --- a/templates/components/common/store-logo.html +++ b/templates/components/common/store-logo.html @@ -1,4 +1,4 @@ - + {{#if settings.store_logo.image}} {{#if theme_settings.logo_size '===' 'original'}} {{settings.store_logo.title}} diff --git a/templates/components/faceted-search/facets/hierarchy.html b/templates/components/faceted-search/facets/hierarchy.html index f9d0e35f30..86024f8fc8 100644 --- a/templates/components/faceted-search/facets/hierarchy.html +++ b/templates/components/faceted-search/facets/hierarchy.html @@ -14,9 +14,7 @@ data-faceted-search-facet> {{{sanitize title}}} {{#if ../show_product_counts}} - {{#if count}} - ({{count}}) - {{/if}} + ({{count}}) {{/if}} {{#if children}} diff --git a/templates/components/faceted-search/facets/range.html b/templates/components/faceted-search/facets/range.html index 82770b898f..6fd95bc3d6 100644 --- a/templates/components/faceted-search/facets/range.html +++ b/templates/components/faceted-search/facets/range.html @@ -3,9 +3,6 @@
- {{#each current_selected_items}} - - {{/each}} {{#if this.sort}} diff --git a/templates/components/products/add-to-cart.html b/templates/components/products/add-to-cart.html index 55c0041707..b5474b01fd 100644 --- a/templates/components/products/add-to-cart.html +++ b/templates/components/products/add-to-cart.html @@ -86,4 +86,4 @@ document.getElementById("form-action-addToCart").addEventListener('click',function (){ _learnq.push(['track', 'Added to Cart', item]); }); - \ No newline at end of file + diff --git a/templates/components/products/options/swatch.html b/templates/components/products/options/swatch.html index d3a5fb0a4e..8470a42f97 100644 --- a/templates/components/products/options/swatch.html +++ b/templates/components/products/options/swatch.html @@ -1,5 +1,5 @@ -
-
{{/partial}} {{> layout/base}} diff --git a/templates/pages/errors/generic.html b/templates/pages/errors/generic.html index 84a05925ca..65f37caa27 100644 --- a/templates/pages/errors/generic.html +++ b/templates/pages/errors/generic.html @@ -1,13 +1,13 @@ {{#partial "page"}} -
+

{{lang 'server_error.page_heading'}}

{{lang 'server_error.message'}}

-
+
{{/partial}} {{> layout/base}} diff --git a/templates/pages/gift-certificate/balance.html b/templates/pages/gift-certificate/balance.html index 325adf22ce..96176dae0d 100644 --- a/templates/pages/gift-certificate/balance.html +++ b/templates/pages/gift-certificate/balance.html @@ -3,7 +3,7 @@

{{lang 'gift_certificate.heading' }}

{{> components/gift-certificate/navigation gift_page='balance'}} -
+
- + {{/partial}} {{> layout/base}} diff --git a/templates/pages/gift-certificate/purchase.html b/templates/pages/gift-certificate/purchase.html index 08c1d14ee0..6b6e13fe87 100644 --- a/templates/pages/gift-certificate/purchase.html +++ b/templates/pages/gift-certificate/purchase.html @@ -3,7 +3,7 @@

{{lang 'gift_certificate.heading' }}

{{> components/gift-certificate/navigation gift_page='purchase'}} -
+ -
+ {{/partial}} {{> layout/base}} diff --git a/templates/pages/gift-certificate/redeem.html b/templates/pages/gift-certificate/redeem.html index f78a681152..91d189b77f 100644 --- a/templates/pages/gift-certificate/redeem.html +++ b/templates/pages/gift-certificate/redeem.html @@ -3,7 +3,7 @@

{{lang 'gift_certificate.heading' }}

{{> components/gift-certificate/navigation gift_page='redeem'}} -
+
+ {{/partial}} {{> layout/base}} diff --git a/templates/pages/page.html b/templates/pages/page.html index 9e65e24aaf..0572768dda 100644 --- a/templates/pages/page.html +++ b/templates/pages/page.html @@ -2,7 +2,7 @@ {{> components/common/breadcrumbs breadcrumbs=breadcrumbs}} -
+
{{#unless theme_settings.hide_page_heading }}

{{ page.title }}

{{/unless}} @@ -37,7 +37,7 @@
{{title}}
{{/each}} {{/if}} -
+ {{/partial}} diff --git a/templates/pages/product.html b/templates/pages/product.html index 51c8f72b85..f94ee9e762 100644 --- a/templates/pages/product.html +++ b/templates/pages/product.html @@ -20,7 +20,7 @@ {{> components/common/alert/alert-info message}} {{/each}} -
+
{{> components/products/product-view schema=true }} {{{region name="product_below_content"}}} diff --git a/templates/pages/search.html b/templates/pages/search.html index f4031a0d6b..416a57529f 100644 --- a/templates/pages/search.html +++ b/templates/pages/search.html @@ -4,6 +4,7 @@ --- {{inject 'categoryTree' forms.search.category_options}} {{inject 'searchProductsPerPage' theme_settings.searchpage_products_per_page}} +{{inject 'searchResultsCount' (lang 'search.results.count' count=result_count search_query=(sanitize forms.search.query))}} {{#partial "head"}} {{#if pagination.product_results.previous}} @@ -61,7 +62,7 @@ {{> components/faceted-search/index product_results}} {{/if}} -
+
{{#if forms.search.has_suggestions}}
@@ -125,14 +126,6 @@
{{lang 'forms.search.suggestions.title'}}
{{/if}} -

- {{{lang 'search.results.count' count=result_count search_query=(sanitize forms.search.query)}}} -

-
{{> components/search/content-listing}}
@@ -142,7 +135,7 @@
{{lang 'forms.search.suggestions.title'}}
{{{region name="search_below_content"}}} -
+
{{/partial}}