From b2ca364cd3ec4c8b4fe9c293245bc19025cb227c Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Thu, 9 Feb 2023 15:31:49 -0800 Subject: [PATCH 01/24] Initial Implementation --- .../components/experiece/carousel/index.jsx | 153 +++++ .../app/pages/page-viewer/index.jsx | 51 ++ .../app/pages/page-viewer/sample-page.json | 608 ++++++++++++++++++ .../template-retail-react-app/app/routes.jsx | 5 + packages/template-retail-react-app/app/ssr.js | 8 +- .../template-retail-react-app/package.json | 1 + 6 files changed, 825 insertions(+), 1 deletion(-) create mode 100644 packages/template-retail-react-app/app/components/experiece/carousel/index.jsx create mode 100644 packages/template-retail-react-app/app/pages/page-viewer/index.jsx create mode 100644 packages/template-retail-react-app/app/pages/page-viewer/sample-page.json diff --git a/packages/template-retail-react-app/app/components/experiece/carousel/index.jsx b/packages/template-retail-react-app/app/components/experiece/carousel/index.jsx new file mode 100644 index 0000000000..2bb4343cec --- /dev/null +++ b/packages/template-retail-react-app/app/components/experiece/carousel/index.jsx @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2023, Salesforce, Inc. + * All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause + */ +import React, {useRef} from 'react' +import PropTypes from 'prop-types' +import { + AspectRatio, + Box, + Heading, + IconButton, + Stack + // Skeleton, + // useBreakpoint +} from '@chakra-ui/react' +import {Component} from 'commerce-sdk-react-preview/components' +import {ChevronLeftIcon, ChevronRightIcon} from '../../icons' + +const Carousel = (props = {}) => { + const scrollRef = useRef() + // const breakpoint = useBreakpoint() + + const { + textHeadline, + regions, + // eslint-disable-next-line no-unused-vars + xsCarouselIndicators = false, + // eslint-disable-next-line no-unused-vars + smCarouselIndicators = false, + // eslint-disable-next-line no-unused-vars + mdCarouselIndicators = false, + xsCarouselControls = false, + smCarouselControls = false, + xsCarouselSlidesToDisplay = 1, + smCarouselSlidesToDisplay = 1, + mdCarouselSlidesToDisplay = 1 + } = props + + const controlDisplay = { + base: 'none', + sm: xsCarouselControls ? 'block' : 'none', + md: smCarouselControls ? 'block' : 'none', + lg: 'block' + } + + const itemWidth = { + base: `calc(${100 / xsCarouselSlidesToDisplay}% - 10px)`, + sm: `calc(${100 / smCarouselSlidesToDisplay}% - 10px)`, + md: `calc(${100 / mdCarouselSlidesToDisplay}% - 10px)` + } + + // Scroll the container left or right by 100%. Passing no args or `1` + // scrolls to the right, and passing `-1` scrolls left. + const scroll = (direction = 1) => { + scrollRef.current?.scrollBy({ + top: 0, + left: direction * window.innerWidth, + behavior: 'smooth' + }) + } + + return ( + + + {textHeadline && ( + + {textHeadline} + + )} + + + {regions[0].components.map((component, index) => ( + + + + + + ))} + + + + <> + + } + borderRadius="full" + colorScheme="whiteAlpha" + onClick={() => scroll(-1)} + /> + + + + } + borderRadius="full" + colorScheme="whiteAlpha" + onClick={() => scroll(1)} + /> + + + + ) +} + +Carousel.propTypes = { + textHeadline: PropTypes.string, + regions: PropTypes.array, + xsCarouselIndicators: PropTypes.bool, + smCarouselControls: PropTypes.bool, + mdCarouselIndicators: PropTypes.bool, + xsCarouselControls: PropTypes.bool, + smCarouselIndicators: PropTypes.bool, + xsCarouselSlidesToDisplay: PropTypes.number, + mdCarouselSlidesToDisplay: PropTypes.number, + smCarouselSlidesToDisplay: PropTypes.number +} + +export default Carousel diff --git a/packages/template-retail-react-app/app/pages/page-viewer/index.jsx b/packages/template-retail-react-app/app/pages/page-viewer/index.jsx new file mode 100644 index 0000000000..1556b2893f --- /dev/null +++ b/packages/template-retail-react-app/app/pages/page-viewer/index.jsx @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023, Salesforce, Inc. + * All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause + */ +import React from 'react' +import {Page, Region} from 'commerce-sdk-react-preview/components' +import SamplePage from './sample-page.json' +import Carousel from '../../components/experiece/carousel' + +const componentMapProxy = new Proxy( + {}, + { + // eslint-disable-next-line no-unused-vars + get(_target, prop) { + let componentClass + switch (prop) { + case 'commerce_assets.productTile': + componentClass = ({index}) => ( + + ) + break + case 'commerce_layouts.carousel': + componentClass = Carousel + break + default: + componentClass = (props) => ( +
+ {props.typeId} + {props?.regions?.map((region) => ( + + ))} +
+ ) + } + + return componentClass + } + } +) + +const PageViewer = () => { + return +} + +export default PageViewer diff --git a/packages/template-retail-react-app/app/pages/page-viewer/sample-page.json b/packages/template-retail-react-app/app/pages/page-viewer/sample-page.json new file mode 100644 index 0000000000..e3530f8c18 --- /dev/null +++ b/packages/template-retail-react-app/app/pages/page-viewer/sample-page.json @@ -0,0 +1,608 @@ +{ + "data": {}, + "description": "Sample homepage", + "id": "homepage-example", + "name": "homepage-example", + "pageDescription": "page description", + "pageKeywords": "meta keywords", + "pageTitle": "page title", + "regions": [ + { + "id": "headerbanner" + }, + { + "components": [ + { + "data": {}, + "id": "eb3ba0039c140b78f32810d7b1", + "regions": [ + { + "components": [ + { + "data": { + "bannerMessage": "

We're Taking Sale To the Next Level! 80% OFF!

" + }, + "id": "f21da510024de04a5980bdfb72", + "typeId": "commerce_assets.campaignBanner" + }, + { + "data": {}, + "id": "08d21a8eab4ea1cd982d8b5c60", + "typeId": "commerce_assets.imageAndText" + }, + { + "data": { + "ITCLink": "https://development-functional38-qa222.demandware.net/s/RefArchGlobal/new%20arrivals/?lang=en_GB", + "image": { + "_type": "Image", + "focalPoint": { + "_type": "Imagefocalpoint", + "x": 0.5, + "y": 0.5 + }, + "url": "https://development-functional38-qa222.demandware.net/on/demandware.static/-/Library-Sites-RefArchSharedLibrary/default/dw5cc73df7/placeholder%20410x307.5.png" + }, + "heading": "

Summer Look

Shop Now

" + }, + "id": "72a40c2ba402656f1744c91471", + "typeId": "commerce_assets.imageAndText" + }, + { + "data": { + "category2": "mens", + "image": { + "_type": "Image", + "focalPoint": { + "_type": "Imagefocalpoint", + "x": 0.5, + "y": 0.5 + }, + "metaData": { + "_type": "Imagemetadata", + "height": 150, + "width": 1 + }, + "url": "https://development-functional38-qa222.demandware.net/on/demandware.static/-/Library-Sites-RefArchSharedLibrary/default/dw473150c3/gray.png" + }, + "category3": "womens-accessories-shoes", + "category4": "womens-accessories-scarves", + "category5": "mens-accessories", + "customCategoryName1": "Women's New Arrivals", + "category1": "womens", + "customCategoryName2": "Men's New Arrivals", + "applyImageShade": false, + "textHeadline": "

Shop Category

", + "changeTextColor": false + }, + "id": "2988c7cd5e2643a99553bdc54f", + "typeId": "commerce_assets.category" + }, + { + "data": { + "textHeadline": "Popular Catalogs" + }, + "id": "b1b243d7a35161cae990cb1ab9", + "regions": [ + { + "components": [ + { + "data": { + "catDisplayName": "Outfits", + "category": "newarrivals-womens" + }, + "id": "a6e5cde39b16c65d969f312e0d", + "typeId": "commerce_assets.popularCategory" + }, + { + "data": { + "catDisplayName": "Tops", + "category": "womens-clothing-tops" + }, + "id": "d34cd47d9e2e36e5fc9f658caf", + "typeId": "commerce_assets.popularCategory" + }, + { + "data": { + "category": "womens-clothing-dresses" + }, + "id": "ad5ce74d73bc733e93b3c81df0", + "typeId": "commerce_assets.popularCategory" + }, + { + "data": { + "category": "womens-clothing-bottoms" + }, + "id": "22e532910def38f170498c2367", + "typeId": "commerce_assets.popularCategory" + }, + { + "data": { + "catDisplayName": "Jackets & Coats", + "category": "womens-clothing-jackets" + }, + "id": "0404c7e4a19b2ba8d62f814edd", + "typeId": "commerce_assets.popularCategory" + }, + { + "data": { + "catDisplayName": "Feeling Red", + "category": "newarrivals-womens" + }, + "id": "b2c8047100a6ce1d334c83a02e", + "typeId": "commerce_assets.popularCategory" + } + ], + "id": "categories" + } + ], + "typeId": "commerce_layouts.popularCategories" + } + ], + "id": "column1" + } + ], + "typeId": "commerce_layouts.mobileGrid1r1c" + }, + { + "data": { + "xsCarouselIndicators": false, + "smCarouselControls": true, + "mdCarouselIndicators": false, + "xsCarouselControls": true, + "smCarouselIndicators": false, + "mdCarouselControls": true, + "xsCarouselSlidesToDisplay": 1, + "mdCarouselSlidesToDisplay": 5, + "textHeadline": "You May Also Like", + "smCarouselSlidesToDisplay": 3 + }, + "id": "604a71c075ebac37052361ac28", + "regions": [ + { + "components": [ + { + "data": { + "product": "25696881M", + "displayRatings": false + }, + "id": "14bc311d27f72374e01d843d0e", + "typeId": "commerce_assets.productTile" + }, + { + "data": { + "product": "25695451M", + "displayRatings": false + }, + "id": "4ef33d8773384bf09bc0fd28af", + "typeId": "commerce_assets.productTile" + }, + { + "data": { + "product": "25589165M", + "displayRatings": false + }, + "id": "8be9091c241e957a0ee9eb1114", + "typeId": "commerce_assets.productTile" + }, + { + "data": { + "product": "25688608M", + "displayRatings": false + }, + "id": "b35dd0d793153420b9e71dbbdf", + "typeId": "commerce_assets.productTile" + }, + { + "data": { + "product": "25778945M", + "displayRatings": false + }, + "id": "c2c4fca566b40c84b7a0c368ce", + "typeId": "commerce_assets.productTile" + }, + { + "data": { + "product": "25778945M", + "displayRatings": false + }, + "id": "c2d4fca566b40c84b7a0c368ce", + "typeId": "commerce_assets.productTile" + }, + { + "data": { + "product": "25778945M", + "displayRatings": false + }, + "id": "csc4fca566b40c84b7a0c368ce", + "typeId": "commerce_assets.productTile" + }, + { + "data": { + "product": "25778945M", + "displayRatings": false + }, + "id": "c2c4fca566b40cd4b7a0c368ce", + "typeId": "commerce_assets.productTile" + }, + { + "data": { + "product": "25778945M", + "displayRatings": false + }, + "id": "c2c4fca566b40c84bsa0c368ce", + "typeId": "commerce_assets.productTile" + }, + { + "data": { + "product": "25778945M", + "displayRatings": false + }, + "id": "c2c4fca566b40c84b7a0c368fe", + "typeId": "commerce_assets.productTile" + } + ], + "id": "slides" + } + ], + "typeId": "commerce_layouts.carousel" + }, + { + "data": { + "richText": "

What's New Trending

" + }, + "id": "48754edd8c9777cb6b709b49ec", + "typeId": "commerce_assets.editorialRichText" + }, + { + "data": {}, + "id": "e51cd7f6192e1ba89a826099d2", + "regions": [ + { + "components": [ + { + "data": { + "ITCLink": "https://development-functional38-qa222.demandware.net/s/RefArchGlobal/mens/clothing/dress%20shirts/?lang=en_GB", + "ITCText": "

Shirts

", + "image": { + "_type": "Image", + "focalPoint": { + "_type": "Imagefocalpoint", + "x": 0.5, + "y": 0.5 + }, + "url": "https://development-functional38-qa222.demandware.net/on/demandware.static/-/Library-Sites-RefArchSharedLibrary/default/dwaa1b7596/placeholder%20410x410.png" + } + }, + "id": "35ef9944c87fb28761edf389e1", + "typeId": "commerce_assets.imageAndText" + } + ], + "id": "column1" + }, + { + "components": [ + { + "data": { + "ITCText": "

Pants

", + "image": { + "_type": "Image", + "focalPoint": { + "_type": "Imagefocalpoint", + "x": 0.5, + "y": 0.5 + }, + "url": "https://development-functional38-qa222.demandware.net/on/demandware.static/-/Library-Sites-RefArchSharedLibrary/default/dwaa1b7596/placeholder%20410x410.png" + } + }, + "id": "932c4631cd219ab8a36a20aa23", + "typeId": "commerce_assets.imageAndText" + } + ], + "id": "column2" + }, + { + "components": [ + { + "data": { + "ITCLink": "https://development-functional38-qa222.demandware.net/s/RefArchGlobal/new%20arrivals/womens/?lang=en_GB", + "ITCText": "

Sunglasses

", + "image": { + "_type": "Image", + "focalPoint": { + "_type": "Imagefocalpoint", + "x": 0.5, + "y": 0.5 + }, + "url": "https://development-functional38-qa222.demandware.net/on/demandware.static/-/Library-Sites-RefArchSharedLibrary/default/dwaa1b7596/placeholder%20410x410.png" + } + }, + "id": "01fc2b169ffc3a3ddaa670e239", + "typeId": "commerce_assets.imageAndText" + } + ], + "id": "column3" + }, + { + "components": [ + { + "data": { + "ITCLink": "https://development-functional38-qa222.demandware.net/s/RefArchGlobal/womens/accessories/scarves/?lang=en_GB", + "ITCText": "

Scarves

", + "image": { + "_type": "Image", + "focalPoint": { + "_type": "Imagefocalpoint", + "x": 0.5, + "y": 0.5 + }, + "url": "https://development-functional38-qa222.demandware.net/on/demandware.static/-/Library-Sites-RefArchSharedLibrary/default/dwaa1b7596/placeholder%20410x410.png" + }, + "heading": "" + }, + "id": "ee6fae89259c4e52d06e31a54a", + "typeId": "commerce_assets.imageAndText" + } + ], + "id": "column4" + }, + { + "components": [ + { + "data": { + "ITCLink": "https://development-functional38-qa222.demandware.net/s/RefArchGlobal/womens/clothing/dresses/?lang=en_GB", + "ITCText": "

Dresses

", + "image": { + "_type": "Image", + "focalPoint": { + "_type": "Imagefocalpoint", + "x": 0.5, + "y": 0.5 + }, + "url": "https://development-functional38-qa222.demandware.net/on/demandware.static/-/Library-Sites-RefArchSharedLibrary/default/dwaa1b7596/placeholder%20410x410.png" + } + }, + "id": "673524e49f7ff570ab3c5cb560", + "typeId": "commerce_assets.imageAndText" + } + ], + "id": "column5" + }, + { + "components": [ + { + "data": { + "ITCLink": "https://development-functional38-qa222.demandware.net/s/RefArchGlobal/mens/?lang=en_GB", + "ITCText": "

Men's

", + "image": { + "_type": "Image", + "focalPoint": { + "_type": "Imagefocalpoint", + "x": 0.5, + "y": 0.5 + }, + "url": "https://development-functional38-qa222.demandware.net/on/demandware.static/-/Library-Sites-RefArchSharedLibrary/default/dwaa1b7596/placeholder%20410x410.png" + } + }, + "id": "c902669568cdf7c4d7f8b74cf9", + "typeId": "commerce_assets.imageAndText" + } + ], + "id": "column6" + } + ], + "typeId": "commerce_layouts.mobileGrid3r2c" + }, + { + "data": {}, + "id": "82e49a64c867b4c218a266dea0", + "regions": [ + { + "components": [ + { + "data": { + "image": { + "_type": "Image", + "focalPoint": { + "_type": "Imagefocalpoint", + "x": 0.5, + "y": 0.5 + }, + "url": "https://development-functional38-qa222.demandware.net/on/demandware.static/-/Library-Sites-RefArchSharedLibrary/default/dwd35a6963/placeholder%20410x179.4.png" + } + }, + "id": "33cddd8f81abade7306c29edad", + "typeId": "commerce_assets.photoTile" + } + ], + "id": "column1" + }, + { + "components": [ + { + "data": { + "richText": "

Hello,

SUNSHINE

Fresh Picks for Warmer Days...

Shop Must Haves

" + }, + "id": "8b4cb78e27e27fe721e76e9af0", + "typeId": "commerce_assets.editorialRichText" + } + ], + "id": "column2" + } + ], + "typeId": "commerce_layouts.mobileGrid2r1c" + }, + { + "data": { + "category2": "mens-clothing-pants", + "image": { + "_type": "Image", + "focalPoint": { + "_type": "Imagefocalpoint", + "x": 0.5, + "y": 0.5 + }, + "metaData": { + "_type": "Imagemetadata", + "height": 150, + "width": 1 + }, + "url": "https://development-functional38-qa222.demandware.net/on/demandware.static/-/Library-Sites-RefArchSharedLibrary/default/dw473150c3/gray.png" + }, + "category3": "womens-accessories-scarves", + "category4": "mens-accessories-gloves", + "customCategoryName1": "Shirts", + "category1": "mens-clothing-dress-shirts", + "applyImageShade": false, + "textHeadline": "

SUMMER SALE 50% OFF

", + "changeTextColor": false + }, + "id": "f4574bbd4b2a6414ee920f692a", + "typeId": "commerce_assets.category" + }, + { + "data": { + "richText": "

Shop The Look

See all

" + }, + "id": "a9127294e7ff4471d1bdb5446c", + "typeId": "commerce_assets.editorialRichText" + }, + { + "data": {}, + "id": "ef20356ba8fc951d79bf02df19", + "regions": [ + { + "components": [ + { + "data": { + "product": "spring-lookM", + "priceDisplay": false + }, + "id": "8b5e6e751e60d706f1f86b86eb", + "typeId": "commerce_assets.shopTheLook" + } + ], + "id": "column1" + }, + { + "components": [ + { + "data": { + "product": "Spring-look-2M", + "priceDisplay": false + }, + "id": "cfdf1818159f462fe8867b5812", + "typeId": "commerce_assets.shopTheLook" + } + ], + "id": "column2" + }, + { + "components": [ + { + "data": { + "image": { + "_type": "Image", + "focalPoint": { + "_type": "Imagefocalpoint", + "x": 0.5, + "y": 0.5 + }, + "url": "https://development-functional38-qa222.demandware.net/on/demandware.static/-/Library-Sites-RefArchSharedLibrary/default/dwaa1b7596/placeholder%20410x410.png" + } + }, + "id": "6ee84af022b410e0adc8953372", + "typeId": "commerce_assets.imageAndText" + } + ], + "id": "column3" + }, + { + "components": [ + { + "data": { + "product": "25695441M", + "priceDisplay": false + }, + "id": "8e51e306ea0e7a468239b967aa", + "typeId": "commerce_assets.shopTheLook" + } + ], + "id": "column4" + }, + { + "components": [ + { + "data": { + "product": "25642436M", + "priceDisplay": false + }, + "id": "ab8e4b826df49a961407fe4d53", + "typeId": "commerce_assets.shopTheLook" + } + ], + "id": "column5" + }, + { + "components": [ + { + "data": { + "product": "25695461M", + "priceDisplay": false + }, + "id": "3e6a2c105138751e32c1bebce3", + "typeId": "commerce_assets.shopTheLook" + } + ], + "id": "column6" + } + ], + "typeId": "commerce_layouts.mobileGridLookBook" + }, + { + "data": {}, + "id": "148ed12df9418d68549713a303", + "regions": [ + { + "components": [ + { + "data": { + "richText": "

Our Inspiration to Style and Trends

Check out Blog

" + }, + "id": "b9043a146951b8be8953259f27", + "typeId": "commerce_assets.editorialRichText" + } + ], + "id": "column1" + }, + { + "components": [ + { + "data": { + "image": { + "_type": "Image", + "focalPoint": { + "_type": "Imagefocalpoint", + "x": 0.5, + "y": 0.5 + }, + "url": "https://development-functional38-qa222.demandware.net/on/demandware.static/-/Library-Sites-RefArchSharedLibrary/default/dwaa1b7596/placeholder%20410x410.png" + } + }, + "id": "3b856e1dbddd8613a2a149bf1a", + "typeId": "commerce_assets.photoTile" + } + ], + "id": "column2" + } + ], + "typeId": "commerce_layouts.mobileGrid2r1c" + } + ], + "id": "main" + }, + { + "id": "legalnotice" + } + ], + "typeId": "storePage" +} diff --git a/packages/template-retail-react-app/app/routes.jsx b/packages/template-retail-react-app/app/routes.jsx index a72f3b8378..011b67cca1 100644 --- a/packages/template-retail-react-app/app/routes.jsx +++ b/packages/template-retail-react-app/app/routes.jsx @@ -36,6 +36,7 @@ const ProductDetail = loadable(() => import('./pages/product-detail'), {fallback const ProductList = loadable(() => import('./pages/product-list'), {fallback}) const Wishlist = loadable(() => import('./pages/account/wishlist'), {fallback}) const PageNotFound = loadable(() => import('./pages/page-not-found')) +const PageViewer = loadable(() => import('./pages/page-viewer'), {fallback}) const routes = [ { @@ -98,6 +99,10 @@ const routes = [ path: '/account/wishlist', component: Wishlist }, + { + path: '/page-viewer', + component: PageViewer + }, { path: '*', component: PageNotFound diff --git a/packages/template-retail-react-app/app/ssr.js b/packages/template-retail-react-app/app/ssr.js index dc7de11469..cc33dc4d3a 100644 --- a/packages/template-retail-react-app/app/ssr.js +++ b/packages/template-retail-react-app/app/ssr.js @@ -39,7 +39,13 @@ const {handler} = runtime.createHandler(options, (app) => { contentSecurityPolicy: { useDefaults: true, directives: { - 'img-src': ["'self'", '*.commercecloud.salesforce.com', 'data:'], + 'img-src': [ + "'self'", + '*.commercecloud.salesforce.com', + 'picsum.photos', + '*.picsum.photos', + 'data:' + ], 'script-src': ["'self'", "'unsafe-eval'", 'storage.googleapis.com'], 'connect-src': ["'self'", 'api.cquotient.com'], diff --git a/packages/template-retail-react-app/package.json b/packages/template-retail-react-app/package.json index b00c5eff76..4e4344dfe9 100644 --- a/packages/template-retail-react-app/package.json +++ b/packages/template-retail-react-app/package.json @@ -27,6 +27,7 @@ "card-validator": "^8.1.0", "chalk": "1.1.3", "commerce-sdk-isomorphic": "^1.5.2", + "commerce-sdk-react-preview": "^2.7.0-dev", "core-js": "2.4.0", "cross-env": "^5.2.0", "cross-fetch": "^3.1.5", From c1a7c29ffc2413a75f8cf96c42b81a194d5fc981 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Mon, 13 Feb 2023 10:47:04 -0800 Subject: [PATCH 02/24] Messing around with padding an scrollers --- .../components/experiece/carousel/index.jsx | 48 ++++++++++++++----- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/packages/template-retail-react-app/app/components/experiece/carousel/index.jsx b/packages/template-retail-react-app/app/components/experiece/carousel/index.jsx index 2bb4343cec..f0efa7cd74 100644 --- a/packages/template-retail-react-app/app/components/experiece/carousel/index.jsx +++ b/packages/template-retail-react-app/app/components/experiece/carousel/index.jsx @@ -12,15 +12,12 @@ import { Heading, IconButton, Stack - // Skeleton, - // useBreakpoint } from '@chakra-ui/react' import {Component} from 'commerce-sdk-react-preview/components' import {ChevronLeftIcon, ChevronRightIcon} from '../../icons' const Carousel = (props = {}) => { const scrollRef = useRef() - // const breakpoint = useBreakpoint() const { textHeadline, @@ -46,9 +43,9 @@ const Carousel = (props = {}) => { } const itemWidth = { - base: `calc(${100 / xsCarouselSlidesToDisplay}% - 10px)`, - sm: `calc(${100 / smCarouselSlidesToDisplay}% - 10px)`, - md: `calc(${100 / mdCarouselSlidesToDisplay}% - 10px)` + base: `calc(${100 / xsCarouselSlidesToDisplay}%)`, + sm: `calc(${100 / smCarouselSlidesToDisplay}%)`, + md: `calc(${100 / mdCarouselSlidesToDisplay}%)` } // Scroll the container left or right by 100%. Passing no args or `1` @@ -56,13 +53,28 @@ const Carousel = (props = {}) => { const scroll = (direction = 1) => { scrollRef.current?.scrollBy({ top: 0, - left: direction * window.innerWidth, + left: (direction * window.innerWidth) / regions[0].components.length, behavior: 'smooth' }) } + const css = ` + ::-webkit-scrollbar { + -webkit-appearance: none; + width: 7px; + } + + ::-webkit-scrollbar-thumb { + border-radius: 4px; + background-color: rgba(0,0,0,.5); + -webkit-box-shadow: 0 0 1px rgba(255,255,255,.5); + } + ` return ( + {textHeadline && ( @@ -73,12 +85,11 @@ const Carousel = (props = {}) => { { key={component?.id || index} flex="0 0 auto" width={itemWidth} - style={{scrollSnapAlign: 'start'}} + style={{scrollSnapAlign: 'start', border: '1px solid black'}} > @@ -98,6 +109,21 @@ const Carousel = (props = {}) => { + <> + + {regions[0].components.map((component, index) => ( + scroll(-1)}>• + ))} + + + <> Date: Mon, 13 Feb 2023 13:30:21 -0800 Subject: [PATCH 03/24] Playing with indicator logic --- .../components/experiece/carousel/index.jsx | 77 ++++++++----------- .../app/pages/page-viewer/sample-page.json | 10 +-- 2 files changed, 38 insertions(+), 49 deletions(-) diff --git a/packages/template-retail-react-app/app/components/experiece/carousel/index.jsx b/packages/template-retail-react-app/app/components/experiece/carousel/index.jsx index f0efa7cd74..dd647e19a6 100644 --- a/packages/template-retail-react-app/app/components/experiece/carousel/index.jsx +++ b/packages/template-retail-react-app/app/components/experiece/carousel/index.jsx @@ -4,29 +4,21 @@ * SPDX-License-Identifier: BSD-3-Clause * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -import React, {useRef} from 'react' +import React, {Fragment, useCallback, useRef} from 'react' import PropTypes from 'prop-types' -import { - AspectRatio, - Box, - Heading, - IconButton, - Stack -} from '@chakra-ui/react' +import {AspectRatio, Box, Heading, IconButton, Stack, useBreakpoint} from '@chakra-ui/react' import {Component} from 'commerce-sdk-react-preview/components' import {ChevronLeftIcon, ChevronRightIcon} from '../../icons' const Carousel = (props = {}) => { const scrollRef = useRef() + const breakpoint = useBreakpoint() const { textHeadline, regions, - // eslint-disable-next-line no-unused-vars xsCarouselIndicators = false, - // eslint-disable-next-line no-unused-vars smCarouselIndicators = false, - // eslint-disable-next-line no-unused-vars mdCarouselIndicators = false, xsCarouselControls = false, smCarouselControls = false, @@ -36,7 +28,7 @@ const Carousel = (props = {}) => { } = props const controlDisplay = { - base: 'none', + base: xsCarouselControls ? 'block' : 'none', sm: xsCarouselControls ? 'block' : 'none', md: smCarouselControls ? 'block' : 'none', lg: 'block' @@ -48,33 +40,43 @@ const Carousel = (props = {}) => { md: `calc(${100 / mdCarouselSlidesToDisplay}%)` } + const overflowXScroll = { + base: xsCarouselIndicators ? 'block' : 'none', + sm: xsCarouselIndicators ? 'block' : 'none', + md: smCarouselIndicators ? 'block' : 'none', + lg: mdCarouselIndicators ? 'block' : 'none' + } + + const components = regions[0]?.components || [] + const itemCount = components.length + // Scroll the container left or right by 100%. Passing no args or `1` // scrolls to the right, and passing `-1` scrolls left. - const scroll = (direction = 1) => { + const scroll = useCallback((direction = 1) => { scrollRef.current?.scrollBy({ top: 0, - left: (direction * window.innerWidth) / regions[0].components.length, + left: (direction * window.innerWidth) / itemCount, behavior: 'smooth' }) - } + }) + // Our indicator implementation uses the scrollbar to show the context of the current + // item selected. Because MacOS hides scroll bars after they come to rest we need to + // force them to show. const css = ` - ::-webkit-scrollbar { + .indicator-scroller::-webkit-scrollbar { + display:${overflowXScroll[breakpoint] || 'block'}; -webkit-appearance: none; - width: 7px; + height: 8px; } - - ::-webkit-scrollbar-thumb { - border-radius: 4px; - background-color: rgba(0,0,0,.5); - -webkit-box-shadow: 0 0 1px rgba(255,255,255,.5); + .indicator-scroller::-webkit-scrollbar-thumb { + background-color: rgba(0, 0, 0, 0.5); } ` + return ( - + {textHeadline && ( @@ -84,6 +86,7 @@ const Carousel = (props = {}) => { { WebkitOverflowScrolling: 'touch' }} > - {regions[0].components.map((component, index) => ( + {components.map((component, index) => ( @@ -109,22 +112,8 @@ const Carousel = (props = {}) => { - <> - - {regions[0].components.map((component, index) => ( - scroll(-1)}>• - ))} - - - - <> + {/* Button Controls */} + { onClick={() => scroll(1)} /> - + ) } diff --git a/packages/template-retail-react-app/app/pages/page-viewer/sample-page.json b/packages/template-retail-react-app/app/pages/page-viewer/sample-page.json index e3530f8c18..e518ee1dfc 100644 --- a/packages/template-retail-react-app/app/pages/page-viewer/sample-page.json +++ b/packages/template-retail-react-app/app/pages/page-viewer/sample-page.json @@ -146,15 +146,15 @@ { "data": { "xsCarouselIndicators": false, - "smCarouselControls": true, - "mdCarouselIndicators": false, + "smCarouselIndicators": true, + "mdCarouselIndicators": true, "xsCarouselControls": true, - "smCarouselIndicators": false, + "smCarouselControls": true, "mdCarouselControls": true, "xsCarouselSlidesToDisplay": 1, + "smCarouselSlidesToDisplay": 3, "mdCarouselSlidesToDisplay": 5, - "textHeadline": "You May Also Like", - "smCarouselSlidesToDisplay": 3 + "textHeadline": "You May Also Like" }, "id": "604a71c075ebac37052361ac28", "regions": [ From aa51d10c08823018c034e3770165410cb1c08a20 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Mon, 13 Feb 2023 15:57:13 -0800 Subject: [PATCH 04/24] Fix scroll display value value. --- .../components/experiece/carousel/index.jsx | 30 ++++++++----- .../app/pages/page-viewer/sample-page.json | 45 ++++++++++++++++--- 2 files changed, 57 insertions(+), 18 deletions(-) diff --git a/packages/template-retail-react-app/app/components/experiece/carousel/index.jsx b/packages/template-retail-react-app/app/components/experiece/carousel/index.jsx index dd647e19a6..c72fad9b05 100644 --- a/packages/template-retail-react-app/app/components/experiece/carousel/index.jsx +++ b/packages/template-retail-react-app/app/components/experiece/carousel/index.jsx @@ -6,13 +6,19 @@ */ import React, {Fragment, useCallback, useRef} from 'react' import PropTypes from 'prop-types' -import {AspectRatio, Box, Heading, IconButton, Stack, useBreakpoint} from '@chakra-ui/react' +import {AspectRatio, Box, Heading, IconButton, Stack, useBreakpointValue} from '@chakra-ui/react' import {Component} from 'commerce-sdk-react-preview/components' import {ChevronLeftIcon, ChevronRightIcon} from '../../icons' +/** + * Display child components in a carousel slider manner. Configurations include the number of + * children to display in view as well as whether or not to show controls and position indicators. + * + * @param {*} props + * @returns + */ const Carousel = (props = {}) => { const scrollRef = useRef() - const breakpoint = useBreakpoint() const { textHeadline, @@ -36,8 +42,9 @@ const Carousel = (props = {}) => { const itemWidth = { base: `calc(${100 / xsCarouselSlidesToDisplay}%)`, - sm: `calc(${100 / smCarouselSlidesToDisplay}%)`, - md: `calc(${100 / mdCarouselSlidesToDisplay}%)` + sm: `calc(${100 / xsCarouselSlidesToDisplay}%)`, + md: `calc(${100 / smCarouselSlidesToDisplay}%)`, + lg: `calc(${100 / mdCarouselSlidesToDisplay}%)` } const overflowXScroll = { @@ -46,6 +53,7 @@ const Carousel = (props = {}) => { md: smCarouselIndicators ? 'block' : 'none', lg: mdCarouselIndicators ? 'block' : 'none' } + const overflowXScrollValue = useBreakpointValue(overflowXScroll) const components = regions[0]?.components || [] const itemCount = components.length @@ -61,11 +69,11 @@ const Carousel = (props = {}) => { }) // Our indicator implementation uses the scrollbar to show the context of the current - // item selected. Because MacOS hides scroll bars after they come to rest we need to + // item selected. Because MacOS hides scroll bars after they come to rest we need to // force them to show. const css = ` .indicator-scroller::-webkit-scrollbar { - display:${overflowXScroll[breakpoint] || 'block'}; + display:${overflowXScrollValue}; -webkit-appearance: none; height: 8px; } @@ -75,7 +83,7 @@ const Carousel = (props = {}) => { ` return ( - + {textHeadline && ( @@ -86,7 +94,7 @@ const Carousel = (props = {}) => { Date: Mon, 13 Feb 2023 16:05:18 -0800 Subject: [PATCH 05/24] Order props --- .../app/components/experiece/carousel/index.jsx | 8 ++++---- .../app/pages/page-viewer/sample-page.json | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/template-retail-react-app/app/components/experiece/carousel/index.jsx b/packages/template-retail-react-app/app/components/experiece/carousel/index.jsx index c72fad9b05..2e056f6e3a 100644 --- a/packages/template-retail-react-app/app/components/experiece/carousel/index.jsx +++ b/packages/template-retail-react-app/app/components/experiece/carousel/index.jsx @@ -164,13 +164,13 @@ Carousel.propTypes = { textHeadline: PropTypes.string, regions: PropTypes.array, xsCarouselIndicators: PropTypes.bool, - smCarouselControls: PropTypes.bool, + smCarouselIndicators: PropTypes.bool, mdCarouselIndicators: PropTypes.bool, xsCarouselControls: PropTypes.bool, - smCarouselIndicators: PropTypes.bool, + smCarouselControls: PropTypes.bool, xsCarouselSlidesToDisplay: PropTypes.oneOf[(1, 2, 3, 4, 5, 6)], - mdCarouselSlidesToDisplay: PropTypes.oneOf[(1, 2, 3, 4, 5, 6)], - smCarouselSlidesToDisplay: PropTypes.oneOf[(1, 2, 3, 4, 5, 6)] + smCarouselSlidesToDisplay: PropTypes.oneOf[(1, 2, 3, 4, 5, 6)], + mdCarouselSlidesToDisplay: PropTypes.oneOf[(1, 2, 3, 4, 5, 6)] } export default Carousel diff --git a/packages/template-retail-react-app/app/pages/page-viewer/sample-page.json b/packages/template-retail-react-app/app/pages/page-viewer/sample-page.json index 7b170bc7de..6c2114937e 100644 --- a/packages/template-retail-react-app/app/pages/page-viewer/sample-page.json +++ b/packages/template-retail-react-app/app/pages/page-viewer/sample-page.json @@ -145,10 +145,10 @@ }, { "data": { - "xsCarouselIndicators": true, + "xsCarouselIndicators": false, "smCarouselIndicators": false, "mdCarouselIndicators": false, - "xsCarouselControls": false, + "xsCarouselControls": true, "smCarouselControls": false, "xsCarouselSlidesToDisplay": 1, "smCarouselSlidesToDisplay": 3, From b28400b1d37ee48acce9ac65e425df923007952d Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Tue, 14 Feb 2023 10:21:16 -0800 Subject: [PATCH 06/24] Clean up JSDoc --- .../components/experiece/carousel/index.jsx | 22 ++++++++++++++----- .../app/pages/page-viewer/sample-page.json | 4 ++-- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/packages/template-retail-react-app/app/components/experiece/carousel/index.jsx b/packages/template-retail-react-app/app/components/experiece/carousel/index.jsx index 2e056f6e3a..65fadbe5b5 100644 --- a/packages/template-retail-react-app/app/components/experiece/carousel/index.jsx +++ b/packages/template-retail-react-app/app/components/experiece/carousel/index.jsx @@ -14,15 +14,24 @@ import {ChevronLeftIcon, ChevronRightIcon} from '../../icons' * Display child components in a carousel slider manner. Configurations include the number of * children to display in view as well as whether or not to show controls and position indicators. * - * @param {*} props - * @returns + * @param {PageProps} props + * @param {string} props.textHeadling - Heading text for the carousel. + * @param {boolean} props.xsCarouselIndicators - Show/Hide carousel indecators/pips on "xs" screens. + * @param {boolean} props.smCarouselIndicators - Show/Hide carousel indecators/pips on "sm" screens. + * @param {boolean} props.mdCarouselIndicators - Show/Hide carousel indecators/pips on "md" screens. + * @param {boolean} props.xsCarouselControls - Show/Hide carousel forward/back controls on "xs" screens. + * @param {boolean} props.smCarouselControls - Show/Hide carousel forward/back controls on "sm" screens. + * @param {number} props.xsCarouselSlidesToDisplay - Number of children that will be rendered in view on "xs" screens. + * @param {number} props.smCarouselSlidesToDisplay - Number of children that will be rendered in view on "sm" screens. + * @param {number} props.mdCarouselSlidesToDisplay - Number of children that will be rendered in view on "md" screens. + * @param {Object []} props.region - The regions passed internally to this component by the `commerce-sdk-react` Page component. + * @returns {React.ReactElement} - Crousel component. */ const Carousel = (props = {}) => { const scrollRef = useRef() const { textHeadline, - regions, xsCarouselIndicators = false, smCarouselIndicators = false, mdCarouselIndicators = false, @@ -30,7 +39,9 @@ const Carousel = (props = {}) => { smCarouselControls = false, xsCarouselSlidesToDisplay = 1, smCarouselSlidesToDisplay = 1, - mdCarouselSlidesToDisplay = 1 + mdCarouselSlidesToDisplay = 1, + // Internally Provided + regions } = props const controlDisplay = { @@ -70,7 +81,8 @@ const Carousel = (props = {}) => { // Our indicator implementation uses the scrollbar to show the context of the current // item selected. Because MacOS hides scroll bars after they come to rest we need to - // force them to show. + // force them to show. Please note that this feature only works on web-kit browsers, + // for all other brosers the scroller/indicator will be shown. const css = ` .indicator-scroller::-webkit-scrollbar { display:${overflowXScrollValue}; diff --git a/packages/template-retail-react-app/app/pages/page-viewer/sample-page.json b/packages/template-retail-react-app/app/pages/page-viewer/sample-page.json index 6c2114937e..d37ab360a9 100644 --- a/packages/template-retail-react-app/app/pages/page-viewer/sample-page.json +++ b/packages/template-retail-react-app/app/pages/page-viewer/sample-page.json @@ -145,9 +145,9 @@ }, { "data": { - "xsCarouselIndicators": false, + "xsCarouselIndicators": true, "smCarouselIndicators": false, - "mdCarouselIndicators": false, + "mdCarouselIndicators": true, "xsCarouselControls": true, "smCarouselControls": false, "xsCarouselSlidesToDisplay": 1, From b1bb944156bea0d66be1a2bd11f40f4c2b42eae3 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Tue, 14 Feb 2023 14:43:23 -0800 Subject: [PATCH 07/24] Fix typo in folder name --- .../app/components/{experiece => experience}/carousel/index.jsx | 0 .../app/components/experience/carousel/index.test.js | 0 .../template-retail-react-app/app/pages/page-viewer/index.jsx | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) rename packages/template-retail-react-app/app/components/{experiece => experience}/carousel/index.jsx (100%) create mode 100644 packages/template-retail-react-app/app/components/experience/carousel/index.test.js diff --git a/packages/template-retail-react-app/app/components/experiece/carousel/index.jsx b/packages/template-retail-react-app/app/components/experience/carousel/index.jsx similarity index 100% rename from packages/template-retail-react-app/app/components/experiece/carousel/index.jsx rename to packages/template-retail-react-app/app/components/experience/carousel/index.jsx diff --git a/packages/template-retail-react-app/app/components/experience/carousel/index.test.js b/packages/template-retail-react-app/app/components/experience/carousel/index.test.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/template-retail-react-app/app/pages/page-viewer/index.jsx b/packages/template-retail-react-app/app/pages/page-viewer/index.jsx index 1556b2893f..598b31fe55 100644 --- a/packages/template-retail-react-app/app/pages/page-viewer/index.jsx +++ b/packages/template-retail-react-app/app/pages/page-viewer/index.jsx @@ -7,7 +7,7 @@ import React from 'react' import {Page, Region} from 'commerce-sdk-react-preview/components' import SamplePage from './sample-page.json' -import Carousel from '../../components/experiece/carousel' +import Carousel from '../../components/experience/carousel' const componentMapProxy = new Proxy( {}, From 915c855df502dcee9c00018d4384f370cb6d8876 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Tue, 14 Feb 2023 16:15:13 -0800 Subject: [PATCH 08/24] Add tests --- .../components/experience/carousel/index.jsx | 29 +++++++------ .../experience/carousel/index.test.js | 40 ++++++++++++++++++ .../app/utils/test-utils.js | 41 +++++++++++++++++++ .../template-retail-react-app/jest.config.js | 3 +- 4 files changed, 99 insertions(+), 14 deletions(-) diff --git a/packages/template-retail-react-app/app/components/experience/carousel/index.jsx b/packages/template-retail-react-app/app/components/experience/carousel/index.jsx index 65fadbe5b5..d0521d5796 100644 --- a/packages/template-retail-react-app/app/components/experience/carousel/index.jsx +++ b/packages/template-retail-react-app/app/components/experience/carousel/index.jsx @@ -84,20 +84,20 @@ const Carousel = (props = {}) => { // force them to show. Please note that this feature only works on web-kit browsers, // for all other brosers the scroller/indicator will be shown. const css = ` - .indicator-scroller::-webkit-scrollbar { + .scroll-indicator::-webkit-scrollbar { display:${overflowXScrollValue}; -webkit-appearance: none; height: 8px; } - .indicator-scroller::-webkit-scrollbar-thumb { + .scroll-indicator::-webkit-scrollbar-thumb { background-color: rgba(0, 0, 0, 0.5); } ` return ( - + - + {textHeadline && ( {textHeadline} @@ -106,7 +106,8 @@ const Carousel = (props = {}) => { { transform="translateY(-50%)" > } borderRadius="full" colorScheme="whiteAlpha" @@ -159,8 +160,8 @@ const Carousel = (props = {}) => { transform="translateY(-50%)" > } borderRadius="full" colorScheme="whiteAlpha" @@ -173,16 +174,18 @@ const Carousel = (props = {}) => { } Carousel.propTypes = { + regions: PropTypes.array.isRequired, textHeadline: PropTypes.string, - regions: PropTypes.array, xsCarouselIndicators: PropTypes.bool, smCarouselIndicators: PropTypes.bool, mdCarouselIndicators: PropTypes.bool, xsCarouselControls: PropTypes.bool, smCarouselControls: PropTypes.bool, - xsCarouselSlidesToDisplay: PropTypes.oneOf[(1, 2, 3, 4, 5, 6)], - smCarouselSlidesToDisplay: PropTypes.oneOf[(1, 2, 3, 4, 5, 6)], - mdCarouselSlidesToDisplay: PropTypes.oneOf[(1, 2, 3, 4, 5, 6)] + xsCarouselSlidesToDisplay: PropTypes.oneOf([1, 2, 3, 4, 5, 6]), + smCarouselSlidesToDisplay: PropTypes.oneOf([1, 2, 3, 4, 5, 6]), + mdCarouselSlidesToDisplay: PropTypes.oneOf([1, 2, 3, 4, 5, 6]) } +Carousel.displayName = 'Carousel' + export default Carousel diff --git a/packages/template-retail-react-app/app/components/experience/carousel/index.test.js b/packages/template-retail-react-app/app/components/experience/carousel/index.test.js index e69de29bb2..19350f01a5 100644 --- a/packages/template-retail-react-app/app/components/experience/carousel/index.test.js +++ b/packages/template-retail-react-app/app/components/experience/carousel/index.test.js @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2023, salesforce.com, inc. + * All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause + */ +import React from 'react' +import {renderWithProviders, withPageProvider} from '../../../utils/test-utils' +import Carousel from './index' + +const SAMPLE_REGION = { + id: 'TEST_REGION', + components: [ + { + id: 'TEST_COMPONENT', + typeId: 'test-component', + data: {} + } + ] +} + +test('Carousel renders without errors', () => { + const {getByTestId} = renderWithProviders() + + expect(getByTestId('carousel')).toBeDefined() + expect(getByTestId('carousel-container')).toBeDefined() + expect(getByTestId('carousel-container-items')).toBeDefined() + expect(getByTestId('carousel-nav-left')).toBeDefined() + expect(getByTestId('carousel-nav-left')).toBeDefined() +}) + +test('Carousel renders region/children without errors', () => { + const CarouselWithPageProvider = withPageProvider(Carousel) + const {getByTestId} = renderWithProviders( + + ) + + expect(getByTestId('carousel')).toBeDefined() + expect(getByTestId('carousel-container-items').childElementCount).toEqual(1) +}) diff --git a/packages/template-retail-react-app/app/utils/test-utils.js b/packages/template-retail-react-app/app/utils/test-utils.js index 02c8958ada..182bc9cacc 100644 --- a/packages/template-retail-react-app/app/utils/test-utils.js +++ b/packages/template-retail-react-app/app/utils/test-utils.js @@ -9,6 +9,7 @@ import {render} from '@testing-library/react' import {BrowserRouter as Router} from 'react-router-dom' import {ChakraProvider} from '@chakra-ui/react' import PropTypes from 'prop-types' +import {PageContext, Region} from 'commerce-sdk-react-preview/components' import theme from '../theme' import CommerceAPI from '../commerce-api' @@ -202,3 +203,43 @@ export const createPathWithDefaults = (path) => { const updatedPath = buildUrl(path, siteAlias || defaultSite.id, defaultLocale) return updatedPath } + +/** + * When testing page designer components wrap them using this higher-order component + * if you plan on using `Region` of `Components` within the components definition. + * + * @param {*} Component + * @param {*} options + * @returns + */ +export const withPageProvider = (Component, options) => { + const providerProps = options?.providerProps || { + value: { + components: new Proxy( + {}, + { + // eslint-disable-next-line no-unused-vars + get(_target, _prop) { + return (props) => ( +
+ {props.typeId} + {props?.regions?.map((region) => ( + + ))} +
+ ) + } + } + ) + } + } + const wrappedComponentName = Component.displayName || Component.name + const WrappedComponent = (props) => ( + + + + ) + WrappedComponent.displayName = `withRouter(${wrappedComponentName})` + + return WrappedComponent +} diff --git a/packages/template-retail-react-app/jest.config.js b/packages/template-retail-react-app/jest.config.js index 5516d0a7f0..c85e8b30cc 100644 --- a/packages/template-retail-react-app/jest.config.js +++ b/packages/template-retail-react-app/jest.config.js @@ -12,7 +12,8 @@ module.exports = { ...base, moduleNameMapper: { ...base.moduleNameMapper, - '^react-router-dom(.*)$': '/node_modules/react-router-dom/index.js' + '^react-router-dom(.*)$': '/node_modules/react-router-dom/index.js', + "^react($|/.+)": "/node_modules/react$1" }, setupFilesAfterEnv: [path.join(__dirname, 'jest-setup.js')], collectCoverageFrom: [ From 66e24ce81ce79a19dfd937fb3eff8522b7c7189e Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Tue, 14 Feb 2023 17:03:48 -0800 Subject: [PATCH 09/24] Typo --- .../app/components/experience/carousel/index.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/template-retail-react-app/app/components/experience/carousel/index.jsx b/packages/template-retail-react-app/app/components/experience/carousel/index.jsx index d0521d5796..b3eaca0cf1 100644 --- a/packages/template-retail-react-app/app/components/experience/carousel/index.jsx +++ b/packages/template-retail-react-app/app/components/experience/carousel/index.jsx @@ -15,7 +15,7 @@ import {ChevronLeftIcon, ChevronRightIcon} from '../../icons' * children to display in view as well as whether or not to show controls and position indicators. * * @param {PageProps} props - * @param {string} props.textHeadling - Heading text for the carousel. + * @param {string} props.textHeading - Heading text for the carousel. * @param {boolean} props.xsCarouselIndicators - Show/Hide carousel indecators/pips on "xs" screens. * @param {boolean} props.smCarouselIndicators - Show/Hide carousel indecators/pips on "sm" screens. * @param {boolean} props.mdCarouselIndicators - Show/Hide carousel indecators/pips on "md" screens. From d294ae9124b37b5da6d6eeb5f56bb2f29586ce47 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Thu, 16 Feb 2023 09:43:26 -0800 Subject: [PATCH 10/24] Remove index from component prop value. --- .../app/components/experience/carousel/index.jsx | 2 +- .../template-retail-react-app/app/pages/page-viewer/index.jsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/template-retail-react-app/app/components/experience/carousel/index.jsx b/packages/template-retail-react-app/app/components/experience/carousel/index.jsx index b3eaca0cf1..422a6e08a9 100644 --- a/packages/template-retail-react-app/app/components/experience/carousel/index.jsx +++ b/packages/template-retail-react-app/app/components/experience/carousel/index.jsx @@ -126,7 +126,7 @@ const Carousel = (props = {}) => { style={{scrollSnapAlign: 'start'}} > - +
))} diff --git a/packages/template-retail-react-app/app/pages/page-viewer/index.jsx b/packages/template-retail-react-app/app/pages/page-viewer/index.jsx index 598b31fe55..ccb1d0872a 100644 --- a/packages/template-retail-react-app/app/pages/page-viewer/index.jsx +++ b/packages/template-retail-react-app/app/pages/page-viewer/index.jsx @@ -17,8 +17,8 @@ const componentMapProxy = new Proxy( let componentClass switch (prop) { case 'commerce_assets.productTile': - componentClass = ({index}) => ( - + componentClass = ({id}) => ( + ) break case 'commerce_layouts.carousel': From 2bb5ed3bf0e321ec40223c16b4cf77438ede6b62 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Thu, 16 Feb 2023 10:12:38 -0800 Subject: [PATCH 11/24] Add logic to ensure controls are only shown when overflowing --- .../components/experience/carousel/index.jsx | 26 +++++++++++++------ .../app/pages/page-viewer/sample-page.json | 2 +- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/packages/template-retail-react-app/app/components/experience/carousel/index.jsx b/packages/template-retail-react-app/app/components/experience/carousel/index.jsx index 422a6e08a9..97c04afb5f 100644 --- a/packages/template-retail-react-app/app/components/experience/carousel/index.jsx +++ b/packages/template-retail-react-app/app/components/experience/carousel/index.jsx @@ -4,11 +4,12 @@ * SPDX-License-Identifier: BSD-3-Clause * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -import React, {Fragment, useCallback, useRef} from 'react' +import React, {Fragment, useCallback, useMemo, useRef, useState} from 'react' import PropTypes from 'prop-types' -import {AspectRatio, Box, Heading, IconButton, Stack, useBreakpointValue} from '@chakra-ui/react' +import {AspectRatio, Box, Heading, IconButton, Stack, useBreakpoint, useBreakpointValue} from '@chakra-ui/react' import {Component} from 'commerce-sdk-react-preview/components' import {ChevronLeftIcon, ChevronRightIcon} from '../../icons' +import { useEffect } from 'react' /** * Display child components in a carousel slider manner. Configurations include the number of @@ -29,6 +30,8 @@ import {ChevronLeftIcon, ChevronRightIcon} from '../../icons' */ const Carousel = (props = {}) => { const scrollRef = useRef() + const breakpoint = useBreakpoint() + const [hasOverflow, setHasOverflow] = useState(false) const { textHeadline, @@ -44,12 +47,14 @@ const Carousel = (props = {}) => { regions } = props - const controlDisplay = { - base: xsCarouselControls ? 'block' : 'none', - sm: xsCarouselControls ? 'block' : 'none', - md: smCarouselControls ? 'block' : 'none', - lg: 'block' - } + const controlDisplay = useMemo(() => { + return { + base: xsCarouselControls && hasOverflow ? 'block' : 'none', + sm: xsCarouselControls && hasOverflow ? 'block' : 'none', + md: smCarouselControls && hasOverflow ? 'block' : 'none', + lg: hasOverflow ? 'block' : 'none' + } + }, [hasOverflow]) const itemWidth = { base: `calc(${100 / xsCarouselSlidesToDisplay}%)`, @@ -94,6 +99,11 @@ const Carousel = (props = {}) => { } ` + useEffect(() => { + const {clientWidth, scrollWidth} = scrollRef.current + setHasOverflow(scrollWidth > clientWidth) + }, [breakpoint, props]) + return ( diff --git a/packages/template-retail-react-app/app/pages/page-viewer/sample-page.json b/packages/template-retail-react-app/app/pages/page-viewer/sample-page.json index d37ab360a9..cfd33a5b24 100644 --- a/packages/template-retail-react-app/app/pages/page-viewer/sample-page.json +++ b/packages/template-retail-react-app/app/pages/page-viewer/sample-page.json @@ -152,7 +152,7 @@ "smCarouselControls": false, "xsCarouselSlidesToDisplay": 1, "smCarouselSlidesToDisplay": 3, - "mdCarouselSlidesToDisplay": 5, + "mdCarouselSlidesToDisplay": 6, "textHeadline": "You May Also Like!" }, "id": "604a71c075ebac37052361ac28", From 95e955d9957269eacf3ca38fc5975295ed2f1569 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Thu, 16 Feb 2023 10:35:06 -0800 Subject: [PATCH 12/24] Use sx prop for styling --- .../components/experience/carousel/index.jsx | 61 +++++++++++++++---- 1 file changed, 48 insertions(+), 13 deletions(-) diff --git a/packages/template-retail-react-app/app/components/experience/carousel/index.jsx b/packages/template-retail-react-app/app/components/experience/carousel/index.jsx index 97c04afb5f..bb9d393954 100644 --- a/packages/template-retail-react-app/app/components/experience/carousel/index.jsx +++ b/packages/template-retail-react-app/app/components/experience/carousel/index.jsx @@ -6,10 +6,18 @@ */ import React, {Fragment, useCallback, useMemo, useRef, useState} from 'react' import PropTypes from 'prop-types' -import {AspectRatio, Box, Heading, IconButton, Stack, useBreakpoint, useBreakpointValue} from '@chakra-ui/react' +import { + AspectRatio, + Box, + Heading, + IconButton, + Stack, + useBreakpoint, + useBreakpointValue +} from '@chakra-ui/react' import {Component} from 'commerce-sdk-react-preview/components' import {ChevronLeftIcon, ChevronRightIcon} from '../../icons' -import { useEffect } from 'react' +import {useEffect} from 'react' /** * Display child components in a carousel slider manner. Configurations include the number of @@ -88,16 +96,16 @@ const Carousel = (props = {}) => { // item selected. Because MacOS hides scroll bars after they come to rest we need to // force them to show. Please note that this feature only works on web-kit browsers, // for all other brosers the scroller/indicator will be shown. - const css = ` - .scroll-indicator::-webkit-scrollbar { - display:${overflowXScrollValue}; - -webkit-appearance: none; - height: 8px; + const style = { + '.scroll-indicator::-webkit-scrollbar': { + display: overflowXScrollValue, + ['-webkit-appearance']: `none`, + height: `8px` + }, + '.scroll-indicator::-webkit-scrollbar-thumb': { + backgroundColor: 'rgba(0, 0, 0, 0.5)' } - .scroll-indicator::-webkit-scrollbar-thumb { - background-color: rgba(0, 0, 0, 0.5); - } - ` + } useEffect(() => { const {clientWidth, scrollWidth} = scrollRef.current @@ -105,8 +113,7 @@ const Carousel = (props = {}) => { }, [breakpoint, props]) return ( - - + {textHeadline && ( @@ -143,6 +150,34 @@ const Carousel = (props = {}) => {
+ {/* Indicators */} + + + {components.map((_, index) => ( + + • + + ))} + + + {/* Button Controls */} Date: Fri, 17 Feb 2023 16:00:45 -0800 Subject: [PATCH 13/24] Use local base components --- .../app/components/experience/carousel/index.jsx | 2 +- .../template-retail-react-app/app/pages/page-viewer/index.jsx | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/template-retail-react-app/app/components/experience/carousel/index.jsx b/packages/template-retail-react-app/app/components/experience/carousel/index.jsx index bb9d393954..3e0875d2a5 100644 --- a/packages/template-retail-react-app/app/components/experience/carousel/index.jsx +++ b/packages/template-retail-react-app/app/components/experience/carousel/index.jsx @@ -15,7 +15,7 @@ import { useBreakpoint, useBreakpointValue } from '@chakra-ui/react' -import {Component} from 'commerce-sdk-react-preview/components' +import {Component} from '../component' import {ChevronLeftIcon, ChevronRightIcon} from '../../icons' import {useEffect} from 'react' diff --git a/packages/template-retail-react-app/app/pages/page-viewer/index.jsx b/packages/template-retail-react-app/app/pages/page-viewer/index.jsx index ccb1d0872a..350c25d678 100644 --- a/packages/template-retail-react-app/app/pages/page-viewer/index.jsx +++ b/packages/template-retail-react-app/app/pages/page-viewer/index.jsx @@ -5,7 +5,8 @@ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ import React from 'react' -import {Page, Region} from 'commerce-sdk-react-preview/components' +import {Page} from '../../components/experience/page' +import {Region} from '../../components/experience/region' import SamplePage from './sample-page.json' import Carousel from '../../components/experience/carousel' From df70ef98a4e9bee94bb5b40b82c8c85aa73e6461 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Fri, 17 Feb 2023 16:01:03 -0800 Subject: [PATCH 14/24] Remove indicators --- .../components/experience/carousel/index.jsx | 28 ------------------- 1 file changed, 28 deletions(-) diff --git a/packages/template-retail-react-app/app/components/experience/carousel/index.jsx b/packages/template-retail-react-app/app/components/experience/carousel/index.jsx index 3e0875d2a5..48226f1081 100644 --- a/packages/template-retail-react-app/app/components/experience/carousel/index.jsx +++ b/packages/template-retail-react-app/app/components/experience/carousel/index.jsx @@ -150,34 +150,6 @@ const Carousel = (props = {}) => {
- {/* Indicators */} - - - {components.map((_, index) => ( - - • - - ))} - - - {/* Button Controls */} Date: Thu, 23 Feb 2023 15:41:44 -0800 Subject: [PATCH 15/24] Move Carousel into "layouts" --- .../{ => layouts}/carousel/index.jsx | 6 +++--- .../{ => layouts}/carousel/index.test.js | 0 .../components/experience/layouts/index.js | 1 + .../app/pages/page-viewer/index.jsx | 21 +++---------------- .../app/pages/page-viewer/utils.js | 15 +++++++------ 5 files changed, 14 insertions(+), 29 deletions(-) rename packages/template-retail-react-app/app/components/experience/{ => layouts}/carousel/index.jsx (98%) rename packages/template-retail-react-app/app/components/experience/{ => layouts}/carousel/index.test.js (100%) diff --git a/packages/template-retail-react-app/app/components/experience/carousel/index.jsx b/packages/template-retail-react-app/app/components/experience/layouts/carousel/index.jsx similarity index 98% rename from packages/template-retail-react-app/app/components/experience/carousel/index.jsx rename to packages/template-retail-react-app/app/components/experience/layouts/carousel/index.jsx index 48226f1081..73100c3464 100644 --- a/packages/template-retail-react-app/app/components/experience/carousel/index.jsx +++ b/packages/template-retail-react-app/app/components/experience/layouts/carousel/index.jsx @@ -15,8 +15,8 @@ import { useBreakpoint, useBreakpointValue } from '@chakra-ui/react' -import {Component} from '../component' -import {ChevronLeftIcon, ChevronRightIcon} from '../../icons' +import {Component} from '../../component' +import {ChevronLeftIcon, ChevronRightIcon} from '../../../icons' import {useEffect} from 'react' /** @@ -36,7 +36,7 @@ import {useEffect} from 'react' * @param {Object []} props.region - The regions passed internally to this component by the `commerce-sdk-react` Page component. * @returns {React.ReactElement} - Crousel component. */ -const Carousel = (props = {}) => { +export const Carousel = (props = {}) => { const scrollRef = useRef() const breakpoint = useBreakpoint() const [hasOverflow, setHasOverflow] = useState(false) diff --git a/packages/template-retail-react-app/app/components/experience/carousel/index.test.js b/packages/template-retail-react-app/app/components/experience/layouts/carousel/index.test.js similarity index 100% rename from packages/template-retail-react-app/app/components/experience/carousel/index.test.js rename to packages/template-retail-react-app/app/components/experience/layouts/carousel/index.test.js diff --git a/packages/template-retail-react-app/app/components/experience/layouts/index.js b/packages/template-retail-react-app/app/components/experience/layouts/index.js index 8a78ee6a86..a0a44cb501 100644 --- a/packages/template-retail-react-app/app/components/experience/layouts/index.js +++ b/packages/template-retail-react-app/app/components/experience/layouts/index.js @@ -5,6 +5,7 @@ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ +export * from './carousel' export * from './mobileGrid1r1c' export * from './mobileGrid2r1c' export * from './mobileGrid2r2c' diff --git a/packages/template-retail-react-app/app/pages/page-viewer/index.jsx b/packages/template-retail-react-app/app/pages/page-viewer/index.jsx index 3f06a49fb6..6820d72a69 100644 --- a/packages/template-retail-react-app/app/pages/page-viewer/index.jsx +++ b/packages/template-retail-react-app/app/pages/page-viewer/index.jsx @@ -7,32 +7,17 @@ import React from 'react' import {componentMapProxy} from './utils' import {Page} from '../../components/experience/page' -import {pageType} from '../../components/experience/types' import {Box} from '@chakra-ui/react' +import SamplePage from './sample-page.json' -const PageViewer = ({page}) => { +const PageViewer = () => { return ( - + ) } -PageViewer.getProps = async ({api}) => { - const page = await api.shopperExperience.getPage({ - parameters: { - pageId: 'layout-example' - } - }) - return { - page - } -} - PageViewer.displayName = 'PageViewer' -PageViewer.propTypes = { - page: pageType.isRequired -} - export default PageViewer diff --git a/packages/template-retail-react-app/app/pages/page-viewer/utils.js b/packages/template-retail-react-app/app/pages/page-viewer/utils.js index fd8b02a64c..f05a95f36a 100644 --- a/packages/template-retail-react-app/app/pages/page-viewer/utils.js +++ b/packages/template-retail-react-app/app/pages/page-viewer/utils.js @@ -45,14 +45,13 @@ export const componentMapProxy = new Proxy( get(_target, prop) { let componentClass switch (prop) { - case 'commerce_assets.editorialRichText': - componentClass = ({richText}) => ( -
- ) + case 'commerce_assets.productTile': + componentClass = withTitle(({id}) => ( + + )) + break + case 'commerce_layouts.carousel': + componentClass = withTitle(Layouts['Carousel']) break case 'commerce_layouts.mobileGrid1r1c': componentClass = withTitle(Layouts['MobileGrid1r1c']) From dcdfb6b4d1465637d2d9f43a15e7a73b6f32e518 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Thu, 23 Feb 2023 15:43:54 -0800 Subject: [PATCH 16/24] Remove mapper This isn't relevant for this PR, but will be later. --- packages/template-retail-react-app/jest.config.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/template-retail-react-app/jest.config.js b/packages/template-retail-react-app/jest.config.js index c85e8b30cc..5516d0a7f0 100644 --- a/packages/template-retail-react-app/jest.config.js +++ b/packages/template-retail-react-app/jest.config.js @@ -12,8 +12,7 @@ module.exports = { ...base, moduleNameMapper: { ...base.moduleNameMapper, - '^react-router-dom(.*)$': '/node_modules/react-router-dom/index.js', - "^react($|/.+)": "/node_modules/react$1" + '^react-router-dom(.*)$': '/node_modules/react-router-dom/index.js' }, setupFilesAfterEnv: [path.join(__dirname, 'jest-setup.js')], collectCoverageFrom: [ From 24900bbe24463509c8d8db61dac85134ebde1639 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Thu, 23 Feb 2023 16:15:46 -0800 Subject: [PATCH 17/24] Update CHANGELOG.md --- packages/template-retail-react-app/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/template-retail-react-app/CHANGELOG.md b/packages/template-retail-react-app/CHANGELOG.md index 6041edf2c3..7ddaa9afb4 100644 --- a/packages/template-retail-react-app/CHANGELOG.md +++ b/packages/template-retail-react-app/CHANGELOG.md @@ -1,4 +1,5 @@ ## v2.7.0-dev (Jan 25, 2023) +- Add Page Designer carousel component [#977](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/977) - Add Page Designer layout components [#993](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/993) ## v2.6.0 (Jan 25, 2023) - Mega menu fixes [#875](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/875) and [#910](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/910) From 58965a1943549d2eb907bfb695de5f9e43359a08 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Thu, 23 Feb 2023 16:16:00 -0800 Subject: [PATCH 18/24] Fix module import --- .../app/components/experience/layouts/carousel/index.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/template-retail-react-app/app/components/experience/layouts/carousel/index.test.js b/packages/template-retail-react-app/app/components/experience/layouts/carousel/index.test.js index 19350f01a5..5a6e804556 100644 --- a/packages/template-retail-react-app/app/components/experience/layouts/carousel/index.test.js +++ b/packages/template-retail-react-app/app/components/experience/layouts/carousel/index.test.js @@ -5,7 +5,7 @@ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ import React from 'react' -import {renderWithProviders, withPageProvider} from '../../../utils/test-utils' +import {renderWithProviders, withPageProvider} from '../../../../utils/test-utils' import Carousel from './index' const SAMPLE_REGION = { From eb4594dd428ea0148ee6efc3779ede0a4cfe7357 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Thu, 23 Feb 2023 16:49:50 -0800 Subject: [PATCH 19/24] Update packages/template-retail-react-app/app/components/experience/layouts/carousel/index.jsx Co-authored-by: Adam Raya --- .../app/components/experience/layouts/carousel/index.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/template-retail-react-app/app/components/experience/layouts/carousel/index.jsx b/packages/template-retail-react-app/app/components/experience/layouts/carousel/index.jsx index 73100c3464..d65e047ce8 100644 --- a/packages/template-retail-react-app/app/components/experience/layouts/carousel/index.jsx +++ b/packages/template-retail-react-app/app/components/experience/layouts/carousel/index.jsx @@ -95,7 +95,7 @@ export const Carousel = (props = {}) => { // Our indicator implementation uses the scrollbar to show the context of the current // item selected. Because MacOS hides scroll bars after they come to rest we need to // force them to show. Please note that this feature only works on web-kit browsers, - // for all other brosers the scroller/indicator will be shown. + // for all other browsers the scroller/indicator will be shown. const style = { '.scroll-indicator::-webkit-scrollbar': { display: overflowXScrollValue, From f39b703af28c41482fd594414368e6e773bef03f Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Thu, 23 Feb 2023 16:49:57 -0800 Subject: [PATCH 20/24] Update packages/template-retail-react-app/app/components/experience/layouts/carousel/index.jsx Co-authored-by: Adam Raya --- .../app/components/experience/layouts/carousel/index.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/template-retail-react-app/app/components/experience/layouts/carousel/index.jsx b/packages/template-retail-react-app/app/components/experience/layouts/carousel/index.jsx index d65e047ce8..d68b678383 100644 --- a/packages/template-retail-react-app/app/components/experience/layouts/carousel/index.jsx +++ b/packages/template-retail-react-app/app/components/experience/layouts/carousel/index.jsx @@ -34,7 +34,7 @@ import {useEffect} from 'react' * @param {number} props.smCarouselSlidesToDisplay - Number of children that will be rendered in view on "sm" screens. * @param {number} props.mdCarouselSlidesToDisplay - Number of children that will be rendered in view on "md" screens. * @param {Object []} props.region - The regions passed internally to this component by the `commerce-sdk-react` Page component. - * @returns {React.ReactElement} - Crousel component. + * @returns {React.ReactElement} - Carousel component. */ export const Carousel = (props = {}) => { const scrollRef = useRef() From 39018bd268e2f6b23a891ebd5cdbd290f861d239 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Thu, 23 Feb 2023 16:50:04 -0800 Subject: [PATCH 21/24] Update packages/template-retail-react-app/app/components/experience/layouts/carousel/index.jsx Co-authored-by: Adam Raya --- .../app/components/experience/layouts/carousel/index.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/template-retail-react-app/app/components/experience/layouts/carousel/index.jsx b/packages/template-retail-react-app/app/components/experience/layouts/carousel/index.jsx index d68b678383..3ca3bc89ca 100644 --- a/packages/template-retail-react-app/app/components/experience/layouts/carousel/index.jsx +++ b/packages/template-retail-react-app/app/components/experience/layouts/carousel/index.jsx @@ -27,7 +27,7 @@ import {useEffect} from 'react' * @param {string} props.textHeading - Heading text for the carousel. * @param {boolean} props.xsCarouselIndicators - Show/Hide carousel indecators/pips on "xs" screens. * @param {boolean} props.smCarouselIndicators - Show/Hide carousel indecators/pips on "sm" screens. - * @param {boolean} props.mdCarouselIndicators - Show/Hide carousel indecators/pips on "md" screens. + * @param {boolean} props.mdCarouselIndicators - Show/Hide carousel indicators/pips on "md" screens. * @param {boolean} props.xsCarouselControls - Show/Hide carousel forward/back controls on "xs" screens. * @param {boolean} props.smCarouselControls - Show/Hide carousel forward/back controls on "sm" screens. * @param {number} props.xsCarouselSlidesToDisplay - Number of children that will be rendered in view on "xs" screens. From 9b867901a65caeb8af7798680da5f5153757e686 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Thu, 23 Feb 2023 16:50:09 -0800 Subject: [PATCH 22/24] Update packages/template-retail-react-app/app/components/experience/layouts/carousel/index.jsx Co-authored-by: Adam Raya --- .../app/components/experience/layouts/carousel/index.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/template-retail-react-app/app/components/experience/layouts/carousel/index.jsx b/packages/template-retail-react-app/app/components/experience/layouts/carousel/index.jsx index 3ca3bc89ca..1083056c26 100644 --- a/packages/template-retail-react-app/app/components/experience/layouts/carousel/index.jsx +++ b/packages/template-retail-react-app/app/components/experience/layouts/carousel/index.jsx @@ -26,7 +26,7 @@ import {useEffect} from 'react' * @param {PageProps} props * @param {string} props.textHeading - Heading text for the carousel. * @param {boolean} props.xsCarouselIndicators - Show/Hide carousel indecators/pips on "xs" screens. - * @param {boolean} props.smCarouselIndicators - Show/Hide carousel indecators/pips on "sm" screens. + * @param {boolean} props.smCarouselIndicators - Show/Hide carousel indicators/pips on "sm" screens. * @param {boolean} props.mdCarouselIndicators - Show/Hide carousel indicators/pips on "md" screens. * @param {boolean} props.xsCarouselControls - Show/Hide carousel forward/back controls on "xs" screens. * @param {boolean} props.smCarouselControls - Show/Hide carousel forward/back controls on "sm" screens. From e76c57e549807ff2e1ad1cb22338d4d403988c00 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Thu, 23 Feb 2023 16:50:18 -0800 Subject: [PATCH 23/24] Update packages/template-retail-react-app/app/components/experience/layouts/carousel/index.jsx Co-authored-by: Adam Raya --- .../app/components/experience/layouts/carousel/index.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/template-retail-react-app/app/components/experience/layouts/carousel/index.jsx b/packages/template-retail-react-app/app/components/experience/layouts/carousel/index.jsx index 1083056c26..d4ec1a836a 100644 --- a/packages/template-retail-react-app/app/components/experience/layouts/carousel/index.jsx +++ b/packages/template-retail-react-app/app/components/experience/layouts/carousel/index.jsx @@ -25,7 +25,7 @@ import {useEffect} from 'react' * * @param {PageProps} props * @param {string} props.textHeading - Heading text for the carousel. - * @param {boolean} props.xsCarouselIndicators - Show/Hide carousel indecators/pips on "xs" screens. + * @param {boolean} props.xsCarouselIndicators - Show/Hide carousel indicators/pips on "xs" screens. * @param {boolean} props.smCarouselIndicators - Show/Hide carousel indicators/pips on "sm" screens. * @param {boolean} props.mdCarouselIndicators - Show/Hide carousel indicators/pips on "md" screens. * @param {boolean} props.xsCarouselControls - Show/Hide carousel forward/back controls on "xs" screens. From cd028ebcb48a4a1d33e9e927f7dc100c92f05c04 Mon Sep 17 00:00:00 2001 From: Ben Chypak Date: Thu, 23 Feb 2023 16:53:20 -0800 Subject: [PATCH 24/24] Remove testing page --- .../app/pages/page-viewer/index.jsx | 23 - .../app/pages/page-viewer/sample-page.json | 639 ------------------ .../app/pages/page-viewer/utils.js | 92 --- .../template-retail-react-app/app/routes.jsx | 5 - packages/template-retail-react-app/app/ssr.js | 8 +- 5 files changed, 1 insertion(+), 766 deletions(-) delete mode 100644 packages/template-retail-react-app/app/pages/page-viewer/index.jsx delete mode 100644 packages/template-retail-react-app/app/pages/page-viewer/sample-page.json delete mode 100644 packages/template-retail-react-app/app/pages/page-viewer/utils.js diff --git a/packages/template-retail-react-app/app/pages/page-viewer/index.jsx b/packages/template-retail-react-app/app/pages/page-viewer/index.jsx deleted file mode 100644 index 6820d72a69..0000000000 --- a/packages/template-retail-react-app/app/pages/page-viewer/index.jsx +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2023, Salesforce, Inc. - * All rights reserved. - * SPDX-License-Identifier: BSD-3-Clause - * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause - */ -import React from 'react' -import {componentMapProxy} from './utils' -import {Page} from '../../components/experience/page' -import {Box} from '@chakra-ui/react' -import SamplePage from './sample-page.json' - -const PageViewer = () => { - return ( - - - - ) -} - -PageViewer.displayName = 'PageViewer' - -export default PageViewer diff --git a/packages/template-retail-react-app/app/pages/page-viewer/sample-page.json b/packages/template-retail-react-app/app/pages/page-viewer/sample-page.json deleted file mode 100644 index cfd33a5b24..0000000000 --- a/packages/template-retail-react-app/app/pages/page-viewer/sample-page.json +++ /dev/null @@ -1,639 +0,0 @@ -{ - "data": {}, - "description": "Sample homepage", - "id": "homepage-example", - "name": "homepage-example", - "pageDescription": "page description", - "pageKeywords": "meta keywords", - "pageTitle": "page title", - "regions": [ - { - "id": "headerbanner" - }, - { - "components": [ - { - "data": {}, - "id": "eb3ba0039c140b78f32810d7b1", - "regions": [ - { - "components": [ - { - "data": { - "bannerMessage": "

We're Taking Sale To the Next Level! 80% OFF!

" - }, - "id": "f21da510024de04a5980bdfb72", - "typeId": "commerce_assets.campaignBanner" - }, - { - "data": {}, - "id": "08d21a8eab4ea1cd982d8b5c60", - "typeId": "commerce_assets.imageAndText" - }, - { - "data": { - "ITCLink": "https://development-functional38-qa222.demandware.net/s/RefArchGlobal/new%20arrivals/?lang=en_GB", - "image": { - "_type": "Image", - "focalPoint": { - "_type": "Imagefocalpoint", - "x": 0.5, - "y": 0.5 - }, - "url": "https://development-functional38-qa222.demandware.net/on/demandware.static/-/Library-Sites-RefArchSharedLibrary/default/dw5cc73df7/placeholder%20410x307.5.png" - }, - "heading": "

Summer Look

Shop Now

" - }, - "id": "72a40c2ba402656f1744c91471", - "typeId": "commerce_assets.imageAndText" - }, - { - "data": { - "category2": "mens", - "image": { - "_type": "Image", - "focalPoint": { - "_type": "Imagefocalpoint", - "x": 0.5, - "y": 0.5 - }, - "metaData": { - "_type": "Imagemetadata", - "height": 150, - "width": 1 - }, - "url": "https://development-functional38-qa222.demandware.net/on/demandware.static/-/Library-Sites-RefArchSharedLibrary/default/dw473150c3/gray.png" - }, - "category3": "womens-accessories-shoes", - "category4": "womens-accessories-scarves", - "category5": "mens-accessories", - "customCategoryName1": "Women's New Arrivals", - "category1": "womens", - "customCategoryName2": "Men's New Arrivals", - "applyImageShade": false, - "textHeadline": "

Shop Category

", - "changeTextColor": false - }, - "id": "2988c7cd5e2643a99553bdc54f", - "typeId": "commerce_assets.category" - }, - { - "data": { - "textHeadline": "Popular Catalogs" - }, - "id": "b1b243d7a35161cae990cb1ab9", - "regions": [ - { - "components": [ - { - "data": { - "catDisplayName": "Outfits", - "category": "newarrivals-womens" - }, - "id": "a6e5cde39b16c65d969f312e0d", - "typeId": "commerce_assets.popularCategory" - }, - { - "data": { - "catDisplayName": "Tops", - "category": "womens-clothing-tops" - }, - "id": "d34cd47d9e2e36e5fc9f658caf", - "typeId": "commerce_assets.popularCategory" - }, - { - "data": { - "category": "womens-clothing-dresses" - }, - "id": "ad5ce74d73bc733e93b3c81df0", - "typeId": "commerce_assets.popularCategory" - }, - { - "data": { - "category": "womens-clothing-bottoms" - }, - "id": "22e532910def38f170498c2367", - "typeId": "commerce_assets.popularCategory" - }, - { - "data": { - "catDisplayName": "Jackets & Coats", - "category": "womens-clothing-jackets" - }, - "id": "0404c7e4a19b2ba8d62f814edd", - "typeId": "commerce_assets.popularCategory" - }, - { - "data": { - "catDisplayName": "Feeling Red", - "category": "newarrivals-womens" - }, - "id": "b2c8047100a6ce1d334c83a02e", - "typeId": "commerce_assets.popularCategory" - } - ], - "id": "categories" - } - ], - "typeId": "commerce_layouts.popularCategories" - } - ], - "id": "column1" - } - ], - "typeId": "commerce_layouts.mobileGrid1r1c" - }, - { - "data": { - "xsCarouselIndicators": true, - "smCarouselIndicators": false, - "mdCarouselIndicators": true, - "xsCarouselControls": true, - "smCarouselControls": false, - "xsCarouselSlidesToDisplay": 1, - "smCarouselSlidesToDisplay": 3, - "mdCarouselSlidesToDisplay": 6, - "textHeadline": "You May Also Like!" - }, - "id": "604a71c075ebac37052361ac28", - "regions": [ - { - "components": [ - { - "data": { - "product": "25696881M", - "displayRatings": false - }, - "id": "14bc311d27f72374e01d843d0e", - "typeId": "commerce_assets.productTile" - }, - { - "data": { - "product": "25695451M", - "displayRatings": false - }, - "id": "4ef33d8773384bf09bc0fd28af", - "typeId": "commerce_assets.productTile" - }, - { - "data": { - "product": "25589165M", - "displayRatings": false - }, - "id": "8be9091c241e957a0ee9eb1114", - "typeId": "commerce_assets.productTile" - }, - { - "data": { - "product": "25688608M", - "displayRatings": false - }, - "id": "b35dd0d793153420b9e71dbbdf", - "typeId": "commerce_assets.productTile" - }, - { - "data": { - "product": "25778945M", - "displayRatings": false - }, - "id": "c2c4fca566b40c84b7a0c368ce", - "typeId": "commerce_assets.productTile" - }, - { - "data": { - "product": "25778945M", - "displayRatings": false - }, - "id": "c2d4fca566b40c84b7a0c368ce", - "typeId": "commerce_assets.productTile" - }, - { - "data": { - "product": "25778945M", - "displayRatings": false - }, - "id": "csc4fca566b40c84b7a0c368ce", - "typeId": "commerce_assets.productTile" - }, - { - "data": { - "product": "25778945M", - "displayRatings": false - }, - "id": "c2c4fca566b40cd4b7a0c368ce", - "typeId": "commerce_assets.productTile" - }, - { - "data": { - "product": "25778945M", - "displayRatings": false - }, - "id": "c2c4fca566b40c84bsa0c368ce", - "typeId": "commerce_assets.productTile" - }, - { - "data": { - "product": "25778945M", - "displayRatings": false - }, - "id": "c2c4fca566b40c84b7a0c368fe", - "typeId": "commerce_assets.productTile" - }, - { - "data": { - "product": "25778945M", - "displayRatings": false - }, - "id": "12c4fca566b40c84b7a0c368fe", - "typeId": "commerce_assets.productTile" - }, - { - "data": { - "product": "25778945M", - "displayRatings": false - }, - "id": "22c4fca566b40c84b7a0c368fe", - "typeId": "commerce_assets.productTile" - }, - { - "data": { - "product": "25778945M", - "displayRatings": false - }, - "id": "32c4fca566b40c84b7a0c368fe", - "typeId": "commerce_assets.productTile" - }, - { - "data": { - "product": "25778945M", - "displayRatings": false - }, - "id": "42c4fca566b40c84b7a0c368fe", - "typeId": "commerce_assets.productTile" - } - ], - "id": "slides" - } - ], - "typeId": "commerce_layouts.carousel" - }, - { - "data": { - "richText": "

What's New Trending

" - }, - "id": "48754edd8c9777cb6b709b49ec", - "typeId": "commerce_assets.editorialRichText" - }, - { - "data": {}, - "id": "e51cd7f6192e1ba89a826099d2", - "regions": [ - { - "components": [ - { - "data": { - "ITCLink": "https://development-functional38-qa222.demandware.net/s/RefArchGlobal/mens/clothing/dress%20shirts/?lang=en_GB", - "ITCText": "

Shirts

", - "image": { - "_type": "Image", - "focalPoint": { - "_type": "Imagefocalpoint", - "x": 0.5, - "y": 0.5 - }, - "url": "https://development-functional38-qa222.demandware.net/on/demandware.static/-/Library-Sites-RefArchSharedLibrary/default/dwaa1b7596/placeholder%20410x410.png" - } - }, - "id": "35ef9944c87fb28761edf389e1", - "typeId": "commerce_assets.imageAndText" - } - ], - "id": "column1" - }, - { - "components": [ - { - "data": { - "ITCText": "

Pants

", - "image": { - "_type": "Image", - "focalPoint": { - "_type": "Imagefocalpoint", - "x": 0.5, - "y": 0.5 - }, - "url": "https://development-functional38-qa222.demandware.net/on/demandware.static/-/Library-Sites-RefArchSharedLibrary/default/dwaa1b7596/placeholder%20410x410.png" - } - }, - "id": "932c4631cd219ab8a36a20aa23", - "typeId": "commerce_assets.imageAndText" - } - ], - "id": "column2" - }, - { - "components": [ - { - "data": { - "ITCLink": "https://development-functional38-qa222.demandware.net/s/RefArchGlobal/new%20arrivals/womens/?lang=en_GB", - "ITCText": "

Sunglasses

", - "image": { - "_type": "Image", - "focalPoint": { - "_type": "Imagefocalpoint", - "x": 0.5, - "y": 0.5 - }, - "url": "https://development-functional38-qa222.demandware.net/on/demandware.static/-/Library-Sites-RefArchSharedLibrary/default/dwaa1b7596/placeholder%20410x410.png" - } - }, - "id": "01fc2b169ffc3a3ddaa670e239", - "typeId": "commerce_assets.imageAndText" - } - ], - "id": "column3" - }, - { - "components": [ - { - "data": { - "ITCLink": "https://development-functional38-qa222.demandware.net/s/RefArchGlobal/womens/accessories/scarves/?lang=en_GB", - "ITCText": "

Scarves

", - "image": { - "_type": "Image", - "focalPoint": { - "_type": "Imagefocalpoint", - "x": 0.5, - "y": 0.5 - }, - "url": "https://development-functional38-qa222.demandware.net/on/demandware.static/-/Library-Sites-RefArchSharedLibrary/default/dwaa1b7596/placeholder%20410x410.png" - }, - "heading": "" - }, - "id": "ee6fae89259c4e52d06e31a54a", - "typeId": "commerce_assets.imageAndText" - } - ], - "id": "column4" - }, - { - "components": [ - { - "data": { - "ITCLink": "https://development-functional38-qa222.demandware.net/s/RefArchGlobal/womens/clothing/dresses/?lang=en_GB", - "ITCText": "

Dresses

", - "image": { - "_type": "Image", - "focalPoint": { - "_type": "Imagefocalpoint", - "x": 0.5, - "y": 0.5 - }, - "url": "https://development-functional38-qa222.demandware.net/on/demandware.static/-/Library-Sites-RefArchSharedLibrary/default/dwaa1b7596/placeholder%20410x410.png" - } - }, - "id": "673524e49f7ff570ab3c5cb560", - "typeId": "commerce_assets.imageAndText" - } - ], - "id": "column5" - }, - { - "components": [ - { - "data": { - "ITCLink": "https://development-functional38-qa222.demandware.net/s/RefArchGlobal/mens/?lang=en_GB", - "ITCText": "

Men's

", - "image": { - "_type": "Image", - "focalPoint": { - "_type": "Imagefocalpoint", - "x": 0.5, - "y": 0.5 - }, - "url": "https://development-functional38-qa222.demandware.net/on/demandware.static/-/Library-Sites-RefArchSharedLibrary/default/dwaa1b7596/placeholder%20410x410.png" - } - }, - "id": "c902669568cdf7c4d7f8b74cf9", - "typeId": "commerce_assets.imageAndText" - } - ], - "id": "column6" - } - ], - "typeId": "commerce_layouts.mobileGrid3r2c" - }, - { - "data": {}, - "id": "82e49a64c867b4c218a266dea0", - "regions": [ - { - "components": [ - { - "data": { - "image": { - "_type": "Image", - "focalPoint": { - "_type": "Imagefocalpoint", - "x": 0.5, - "y": 0.5 - }, - "url": "https://development-functional38-qa222.demandware.net/on/demandware.static/-/Library-Sites-RefArchSharedLibrary/default/dwd35a6963/placeholder%20410x179.4.png" - } - }, - "id": "33cddd8f81abade7306c29edad", - "typeId": "commerce_assets.photoTile" - } - ], - "id": "column1" - }, - { - "components": [ - { - "data": { - "richText": "

Hello,

SUNSHINE

Fresh Picks for Warmer Days...

Shop Must Haves

" - }, - "id": "8b4cb78e27e27fe721e76e9af0", - "typeId": "commerce_assets.editorialRichText" - } - ], - "id": "column2" - } - ], - "typeId": "commerce_layouts.mobileGrid2r1c" - }, - { - "data": { - "category2": "mens-clothing-pants", - "image": { - "_type": "Image", - "focalPoint": { - "_type": "Imagefocalpoint", - "x": 0.5, - "y": 0.5 - }, - "metaData": { - "_type": "Imagemetadata", - "height": 150, - "width": 1 - }, - "url": "https://development-functional38-qa222.demandware.net/on/demandware.static/-/Library-Sites-RefArchSharedLibrary/default/dw473150c3/gray.png" - }, - "category3": "womens-accessories-scarves", - "category4": "mens-accessories-gloves", - "customCategoryName1": "Shirts", - "category1": "mens-clothing-dress-shirts", - "applyImageShade": false, - "textHeadline": "

SUMMER SALE 50% OFF

", - "changeTextColor": false - }, - "id": "f4574bbd4b2a6414ee920f692a", - "typeId": "commerce_assets.category" - }, - { - "data": { - "richText": "

Shop The Look

See all

" - }, - "id": "a9127294e7ff4471d1bdb5446c", - "typeId": "commerce_assets.editorialRichText" - }, - { - "data": {}, - "id": "ef20356ba8fc951d79bf02df19", - "regions": [ - { - "components": [ - { - "data": { - "product": "spring-lookM", - "priceDisplay": false - }, - "id": "8b5e6e751e60d706f1f86b86eb", - "typeId": "commerce_assets.shopTheLook" - } - ], - "id": "column1" - }, - { - "components": [ - { - "data": { - "product": "Spring-look-2M", - "priceDisplay": false - }, - "id": "cfdf1818159f462fe8867b5812", - "typeId": "commerce_assets.shopTheLook" - } - ], - "id": "column2" - }, - { - "components": [ - { - "data": { - "image": { - "_type": "Image", - "focalPoint": { - "_type": "Imagefocalpoint", - "x": 0.5, - "y": 0.5 - }, - "url": "https://development-functional38-qa222.demandware.net/on/demandware.static/-/Library-Sites-RefArchSharedLibrary/default/dwaa1b7596/placeholder%20410x410.png" - } - }, - "id": "6ee84af022b410e0adc8953372", - "typeId": "commerce_assets.imageAndText" - } - ], - "id": "column3" - }, - { - "components": [ - { - "data": { - "product": "25695441M", - "priceDisplay": false - }, - "id": "8e51e306ea0e7a468239b967aa", - "typeId": "commerce_assets.shopTheLook" - } - ], - "id": "column4" - }, - { - "components": [ - { - "data": { - "product": "25642436M", - "priceDisplay": false - }, - "id": "ab8e4b826df49a961407fe4d53", - "typeId": "commerce_assets.shopTheLook" - } - ], - "id": "column5" - }, - { - "components": [ - { - "data": { - "product": "25695461M", - "priceDisplay": false - }, - "id": "3e6a2c105138751e32c1bebce3", - "typeId": "commerce_assets.shopTheLook" - } - ], - "id": "column6" - } - ], - "typeId": "commerce_layouts.mobileGridLookBook" - }, - { - "data": {}, - "id": "148ed12df9418d68549713a303", - "regions": [ - { - "components": [ - { - "data": { - "richText": "

Our Inspiration to Style and Trends

Check out Blog

" - }, - "id": "b9043a146951b8be8953259f27", - "typeId": "commerce_assets.editorialRichText" - } - ], - "id": "column1" - }, - { - "components": [ - { - "data": { - "image": { - "_type": "Image", - "focalPoint": { - "_type": "Imagefocalpoint", - "x": 0.5, - "y": 0.5 - }, - "url": "https://development-functional38-qa222.demandware.net/on/demandware.static/-/Library-Sites-RefArchSharedLibrary/default/dwaa1b7596/placeholder%20410x410.png" - } - }, - "id": "3b856e1dbddd8613a2a149bf1a", - "typeId": "commerce_assets.photoTile" - } - ], - "id": "column2" - } - ], - "typeId": "commerce_layouts.mobileGrid2r1c" - } - ], - "id": "main" - }, - { - "id": "legalnotice" - } - ], - "typeId": "storePage" -} diff --git a/packages/template-retail-react-app/app/pages/page-viewer/utils.js b/packages/template-retail-react-app/app/pages/page-viewer/utils.js deleted file mode 100644 index f05a95f36a..0000000000 --- a/packages/template-retail-react-app/app/pages/page-viewer/utils.js +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2023, Salesforce, Inc. - * All rights reserved. - * SPDX-License-Identifier: BSD-3-Clause - * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause - */ -import React from 'react' -import PropTypes from 'prop-types' -import {Region} from '../../components/experience/region' - -import * as Layouts from '../../components/experience/layouts' - -const withTitle = (Component) => { - const WrappedComponent = (props) => { - return ( -
- - {props.typeId.split('.')[1]} - - -
- ) - } - WrappedComponent.propTypes = { - typeId: PropTypes.string - } - - return WrappedComponent -} - -export const componentMapProxy = new Proxy( - {}, - { - // eslint-disable-next-line no-unused-vars - get(_target, prop) { - let componentClass - switch (prop) { - case 'commerce_assets.productTile': - componentClass = withTitle(({id}) => ( - - )) - break - case 'commerce_layouts.carousel': - componentClass = withTitle(Layouts['Carousel']) - break - case 'commerce_layouts.mobileGrid1r1c': - componentClass = withTitle(Layouts['MobileGrid1r1c']) - break - case 'commerce_layouts.mobileGrid2r1c': - componentClass = withTitle(Layouts['MobileGrid2r1c']) - break - case 'commerce_layouts.mobileGrid2r2c': - componentClass = withTitle(Layouts['MobileGrid2r2c']) - break - case 'commerce_layouts.mobileGrid2r3c': - componentClass = withTitle(Layouts['MobileGrid2r3c']) - break - case 'commerce_layouts.mobileGrid3r1c': - componentClass = withTitle(Layouts['MobileGrid3r1c']) - break - case 'commerce_layouts.mobileGrid3r2c': - componentClass = withTitle(Layouts['MobileGrid3r2c']) - break - default: - componentClass = (props) => ( -
- {props.typeId} - {props?.regions?.map((region) => ( - - ))} -
- ) - } - - return componentClass - } - } -) diff --git a/packages/template-retail-react-app/app/routes.jsx b/packages/template-retail-react-app/app/routes.jsx index 011b67cca1..a72f3b8378 100644 --- a/packages/template-retail-react-app/app/routes.jsx +++ b/packages/template-retail-react-app/app/routes.jsx @@ -36,7 +36,6 @@ const ProductDetail = loadable(() => import('./pages/product-detail'), {fallback const ProductList = loadable(() => import('./pages/product-list'), {fallback}) const Wishlist = loadable(() => import('./pages/account/wishlist'), {fallback}) const PageNotFound = loadable(() => import('./pages/page-not-found')) -const PageViewer = loadable(() => import('./pages/page-viewer'), {fallback}) const routes = [ { @@ -99,10 +98,6 @@ const routes = [ path: '/account/wishlist', component: Wishlist }, - { - path: '/page-viewer', - component: PageViewer - }, { path: '*', component: PageNotFound diff --git a/packages/template-retail-react-app/app/ssr.js b/packages/template-retail-react-app/app/ssr.js index cc33dc4d3a..dc7de11469 100644 --- a/packages/template-retail-react-app/app/ssr.js +++ b/packages/template-retail-react-app/app/ssr.js @@ -39,13 +39,7 @@ const {handler} = runtime.createHandler(options, (app) => { contentSecurityPolicy: { useDefaults: true, directives: { - 'img-src': [ - "'self'", - '*.commercecloud.salesforce.com', - 'picsum.photos', - '*.picsum.photos', - 'data:' - ], + 'img-src': ["'self'", '*.commercecloud.salesforce.com', 'data:'], 'script-src': ["'self'", "'unsafe-eval'", 'storage.googleapis.com'], 'connect-src': ["'self'", 'api.cquotient.com'],