Skip to content

Integrate srcSet #693

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 46 commits into from
May 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/components/src/AppHeader/appheader.main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,12 @@ class AppHeaderMain extends Component<AppHeaderMainProps, AppHeaderMainState> {
<div className="main-container-col">
<div className="logo-container">
<Link to={appHeaderLinks.mainPage} className="logo" aria-label="logo image">
<ImageContainer className="logo-image" fileName={headerLogoFileName} imgUrl={headerLogo} />
<ImageContainer
imgClassName="logo-image"
fileName={headerLogoFileName}
types={['svg']}
imgUrl={headerLogo}
/>
</Link>
</div>

Expand Down
2 changes: 1 addition & 1 deletion src/components/src/B2bHomePage/b2b.home.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const heroBannerFileName = 'hero-banner-0.jpg';
const B2BHomePage: React.FunctionComponent = () => (
<div className="home-page-b2b">
<section className="main-banner">
<ImageContainer className="main-banner-image" fileName={heroBannerFileName} imgUrl={heroBanner} />
<ImageContainer imgClassName="main-banner-image" fileName={heroBannerFileName} imgUrl={heroBanner} />
<div className="main-banner-title-wrap">
<div className="container">
<h1 className="goods-heading">{intl.get('main-banner-heading')}</h1>
Expand Down
33 changes: 14 additions & 19 deletions src/components/src/B2cHomePage/b2c.home.page.scss
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,18 @@
width: 100%;
max-height: 100%;
object-fit: cover;
display:flex;

@media (max-width: 991px) {
max-height: 400px;
}
}

&-picture {
width: 100%;
max-height: 100%;
object-fit: cover;
display:flex;

@media (max-width: 991px) {
max-height: 400px;
Expand Down Expand Up @@ -248,7 +260,8 @@

&__cell {
&:first-child {
grid-row: 1 / 3;
grid-row-start: 1;
grid-row-end: 3;

.goods-info {
width: 100%;
Expand Down Expand Up @@ -287,10 +300,6 @@
}

@media (min-width: 481px) {
.goods-info {
width: 50%;
}

.goods-title {
margin-bottom: 30px;
}
Expand Down Expand Up @@ -332,27 +341,13 @@
color: $firstComplimentColor;
}

@media (min-width: 481px) {
.main-goods-image {
width: 50%;
}
}

@media (min-width: 992px) {
.goods-title {
max-width: 185px;
}
}
}

&:nth-child(4) {
@media (min-width: 481px) {
.main-goods-image {
width: 50%;
}
}
}

&:nth-child(5) {
.goods-info {
width: 100%;
Expand Down
40 changes: 20 additions & 20 deletions src/components/src/B2cHomePage/b2c.home.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,16 @@ import productImage6 from '../../../images/site-images/b2c-product-6.png';
import productImage7 from '../../../images/site-images/b2c-product-7.png';


const bannerFileName1 = 'b2c-banner-1.png';
const bannerFileName2 = 'b2c-banner-2.png';
const bannerFileName3 = 'b2c-banner-3.png';
const productFileName1 = 'b2c-product-1.png';
const productFileName2 = 'b2c-product-2.png';
const productFileName3 = 'b2c-product-3.png';
const productFileName4 = 'b2c-product-4.png';
const productFileName5 = 'b2c-product-5.png';
const productFileName6 = 'b2c-product-6.png';
const productFileName7 = 'b2c-product-7.png';
const bannerFileName1 = 'b2c-banner-1';
const bannerFileName2 = 'b2c-banner-2';
const bannerFileName3 = 'b2c-banner-3';
const productFileName1 = 'b2c-product-1';
const productFileName2 = 'b2c-product-2';
const productFileName3 = 'b2c-product-3';
const productFileName4 = 'b2c-product-4';
const productFileName5 = 'b2c-product-5';
const productFileName6 = 'b2c-product-6';
const productFileName7 = 'b2c-product-7';

const B2CHomePage: React.FunctionComponent = () => {
// Set the language-specific configuration for indi integration
Expand All @@ -59,7 +59,7 @@ const B2CHomePage: React.FunctionComponent = () => {
return (
<div className="home-page-b2c">
<section className="main-banner">
<ImageContainer className="main-banner-image" fileName={bannerFileName1} imgUrl={bannerImage1} />
<ImageContainer imgClassName="main-banner-image" pictureClassName="main-banner-image" fileName={bannerFileName1} imgUrl={bannerImage1} />
<div className="main-banner-title-wrap">
<div className="container">
<h1 className="goods-heading">{intl.get('b2c-main-banner-heading')}</h1>
Expand Down Expand Up @@ -90,7 +90,7 @@ const B2CHomePage: React.FunctionComponent = () => {
<button type="button" className="ep-btn primary learn-more-btn">{intl.get('learn-more')}</button>
</div>
</div>
<ImageContainer className="main-goods-image" fileName={productFileName1} imgUrl={productImage1} />
<ImageContainer imgClassName="main-goods-image" pictureClassName="main-goods-picture" fileName={productFileName1} imgUrl={productImage1} />
</div>
</li>
<li className="main-goods__cell">
Expand All @@ -101,7 +101,7 @@ const B2CHomePage: React.FunctionComponent = () => {
<p className="goods-description">{intl.get('b2c-product2-description')}</p>
<button type="button" className="ep-btn primary learn-more-btn">{intl.get('add-to-cart-2')}</button>
</div>
<ImageContainer className="main-goods-image" fileName={productFileName2} imgUrl={productImage2} />
<ImageContainer imgClassName="main-goods-image" pictureClassName="main-goods-picture" fileName={productFileName2} imgUrl={productImage2} />
</div>
</li>
<li className="main-goods__cell">
Expand All @@ -114,7 +114,7 @@ const B2CHomePage: React.FunctionComponent = () => {
</p>
<button type="button" className="ep-btn primary learn-more-btn">{intl.get('b2c-product3-label')}</button>
</div>
<ImageContainer className="main-goods-image" fileName={productFileName3} imgUrl={productImage3} />
<ImageContainer pictureClassName="main-goods-picture" imgClassName="main-goods-image" fileName={productFileName3} imgUrl={productImage3} />
</div>
</li>
<li className="main-goods__cell">
Expand All @@ -126,7 +126,7 @@ const B2CHomePage: React.FunctionComponent = () => {
{intl.get('b2c-product4-description')}
</p>
</div>
<ImageContainer className="main-goods-image" fileName={productFileName4} imgUrl={productImage4} />
<ImageContainer imgClassName="main-goods-image" pictureClassName="main-goods-picture" fileName={productFileName4} imgUrl={productImage4} />
</div>
</li>
<li className="main-goods__cell">
Expand All @@ -137,7 +137,7 @@ const B2CHomePage: React.FunctionComponent = () => {
{intl.get('b2c-product5-heading')}
</p>
</div>
<ImageContainer className="main-goods-image" fileName={productFileName5} imgUrl={productImage5} />
<ImageContainer imgClassName="main-goods-image" pictureClassName="main-goods-picture" fileName={productFileName5} imgUrl={productImage5} />
</div>
</li>
</ul>
Expand All @@ -146,7 +146,7 @@ const B2CHomePage: React.FunctionComponent = () => {
</section>

<section className="main-banner banner-section-2">
<ImageContainer className="main-banner-image" fileName={bannerFileName2} imgUrl={bannerImage2} />
<ImageContainer imgClassName="main-banner-image" pictureClassName="main-banner-image" fileName={bannerFileName2} imgUrl={bannerImage2} />
<div className="main-banner-title-wrap">
<div className="container">
<h2 className="goods-heading">{intl.get('b2c-main-banner-heading2')}</h2>
Expand Down Expand Up @@ -174,7 +174,7 @@ const B2CHomePage: React.FunctionComponent = () => {
<p className="goods-title">{intl.get('b2c-product6-heading')}</p>
<p className="goods-description">{intl.get('b2c-product6-description')}</p>
</div>
<ImageContainer className="main-goods-image" fileName={productFileName6} imgUrl={productImage6} />
<ImageContainer imgClassName="main-goods-image" pictureClassName="main-goods-picture" fileName={productFileName6} imgUrl={productImage6} />
</div>
</li>
<li className="main-goods__cell">
Expand All @@ -184,7 +184,7 @@ const B2CHomePage: React.FunctionComponent = () => {
<p className="goods-title">{intl.get('b2c-product7-heading')}</p>
<p className="goods-description">{intl.get('b2c-product7-description')}</p>
</div>
<ImageContainer className="main-goods-image" fileName={productFileName7} imgUrl={productImage7} />
<ImageContainer imgClassName="main-goods-image" pictureClassName="main-goods-picture" fileName={productFileName7} imgUrl={productImage7} />
</div>
</li>
</ul>
Expand All @@ -193,7 +193,7 @@ const B2CHomePage: React.FunctionComponent = () => {
</section>

<section className="main-banner banner-section-3">
<ImageContainer className="main-banner-image" fileName={bannerFileName3} imgUrl={bannerImage3} />
<ImageContainer imgClassName="main-banner-image" pictureClassName="main-banner-image" fileName={bannerFileName3} imgUrl={bannerImage3} />
<div className="main-banner-title-wrap">
<div className="container">
<h2 className="goods-heading">{intl.get('b2c-main-banner-heading3')}</h2>
Expand Down
4 changes: 4 additions & 0 deletions src/components/src/CartLineItem/cart.lineitem.scss
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
}

.thumbnail-col {
width:100%;
grid-row: 1 / last-line;
position: relative;
display: inline-block;
Expand All @@ -45,6 +46,9 @@
border: 1px solid $firstBorderColor;
width: 100%;
}
picture {
width: 100%;
}
}

.featured {
Expand Down
9 changes: 7 additions & 2 deletions src/components/src/CartLineItem/cart.lineitem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -523,8 +523,13 @@ class CartLineItem extends Component<CartLineItemProps, CartLineItemState> {
)
: ('')
}
<Link to={`${itemDetailLink}/${encodeURIComponent(itemCodeString)}`} title={itemDisplayName}>
<ImageContainer className="cart-lineitem-thumbnail" isSkuImage fileName={itemCodeString} imgUrl={Config.skuImagesUrl.replace('%sku%', itemCodeString)} />
<Link to={`${itemDetailLink}/${encodeURIComponent(itemCodeString)}`}>
<ImageContainer
imgClassName="cart-lineitem-thumbnail"
isSkuImage
fileName={itemCodeString}
imgUrl={Config.skuImagesUrl.replace('%fileName%', `${itemCodeString}.png`)}
/>
</Link>
</div>
<div className="title-options-col">
Expand Down
44 changes: 41 additions & 3 deletions src/components/src/ImageContainer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,29 @@

#### Description

Initially trying to fetch primary file type received from the prop if not found try PNG, if not found try JPG, if not found try SVG etc.
The image container is meant to abstract the Picture html 5 element: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture

The configuration of these file types may be managed within `ep.config.json`. If no file types are provided in the configuration, the image will be used as is provided in the URL.
When given a filename and a list of image type extensions and sizes the component will generate the necessary `<source>` and `<img>` elements necessary for the `<picture>` element. Depending if you set `isSkuImage` to either true or false the src prefix's will be either `Config.siteImagesUrl` or `Config.skuImagesUrl`. If types and sizes are not specified as a prop in the component it will default to what is specified in `Config.ImageContainerSrcs.types` and `Config.ImageContainerSrcs.sizes`.

Example of the ImageContainer configs here:

```
"ImageContainerSrcs": {
"types": ["webp", "jp2", "jpg"],
"sizes": ["768", "1092", "2800"]
}
```

and of ImageContainer source prefix configs here:

```
"skuImagesUrl": "https://ep-demo-assets.s3-us-west-2.amazonaws.com/BELLEVIE/skuImages/%fileName%",
"siteImagesUrl": "https://ep-demo-assets.s3-us-west-2.amazonaws.com/BELLEVIE/siteImages/%fileName%",
```

If the component cannot find a valid source through the generated `<picture>` element it will fallback and show the source that is specified in the `imgUrl` parameter. If even that source is invalid, the component will show its own 'image not found' fallback image when `isSkuImage` is set to true, else nothing will show.

Look in ref-store application and stories for more example usage.

#### Usage

Expand All @@ -15,7 +35,25 @@ import ImageContainer from '../ImageContainer/image.container';
#### Example

```js
<ImageContainer className="parallax-image" fileName={homeEspotParallax1FileName} imgUrl={homeEspotParallax1} />
<ImageContainer
alt="banner one"
imgClassName="main-banner-image"
pictureClassName="main-banner-image"
fileName={bannerFileName1}
imgUrl={bannerImage1}
ImageContainerSrcs={['jp2', 'webp', 'jpg']}
/>
```

generates:

```html
<picture class="main-banner-image">
<source srcset="https://refstoreimgs.s3-us-west-2.amazonaws.com/siteImages/jp2/b2c-banner-1-768w.jp2 768w, https://refstoreimgs.s3-us-west-2.amazonaws.com/siteImages/jp2/b2c-banner-1-1092w.jp2 1092w, https://refstoreimgs.s3-us-west-2.amazonaws.com/siteImages/jp2/b2c-banner-1-2800w.jp2 2800w" type="image/jp2">
<source srcset="https://refstoreimgs.s3-us-west-2.amazonaws.com/siteImages/webp/b2c-banner-1-768w.webp 768w, https://refstoreimgs.s3-us-west-2.amazonaws.com/siteImages/webp/b2c-banner-1-1092w.webp 1092w, https://refstoreimgs.s3-us-west-2.amazonaws.com/siteImages/webp/b2c-banner-1-2800w.webp 2800w" type="image/webp">
<source srcset="https://refstoreimgs.s3-us-west-2.amazonaws.com/siteImages/jpg/b2c-banner-1-768w.jpg 768w, https://refstoreimgs.s3-us-west-2.amazonaws.com/siteImages/jpg/b2c-banner-1-1092w.jpg 1092w, https://refstoreimgs.s3-us-west-2.amazonaws.com/siteImages/jpg/b2c-banner-1-2800w.jpg 2800w" type="image/jpg">
<img class="main-banner-image" alt="banner one" src="/static/media/b2c-banner-1.5ad237f5.png">
</picture>
```

#### Properties
Expand Down
6 changes: 6 additions & 0 deletions src/components/src/ImageContainer/image.container.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
picture {
width: 100%;
img {
width: 100%;
}
}
48 changes: 44 additions & 4 deletions src/components/src/ImageContainer/image.container.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { storiesOf } from '@storybook/react';
import Readme from './README.md';
import ImageContainer from './image.container';
import homeEspotParallax1 from '../../../images/site-images/hero-banner-0.jpg';
import bannerImage3 from '../../../images/site-images/b2c-banner-3.png';

storiesOf('Components|ImageContainer', module)
.addParameters({
Expand All @@ -31,8 +32,47 @@ storiesOf('Components|ImageContainer', module)
sidebar: Readme,
},
})
.add('ImageContainer', () => {
.add('Failure to find matching srcSet in Picture element - fallback to imgUrl', () => {
const homeEspotParallax1FileName = 'hero-banner-0.jpg';

return (<ImageContainer className="parallax-image" fileName={homeEspotParallax1FileName} imgUrl={homeEspotParallax1} />);
});
return (<ImageContainer
imgClassName="parallax-image"
fileName={homeEspotParallax1FileName}
imgUrl={homeEspotParallax1}
/>);
})
.add('Use configs for sizing and typing', () => (
<ImageContainer
imgClassName="main-banner-image"
isSkuImage
pictureClassName="main-banner-image"
fileName="KIDS_SS_HANLEY"
imgUrl={bannerImage3}
/>))
.add('Override sizing breakpoint and different possible types for image', () => (
<ImageContainer
imgClassName="main-banner-image"
pictureClassName="main-banner-image"
isSkuImage
sizes={['1092', '2800']}
types={['jp2', 'webp']}
fileName="KIDS_SS_HANLEY"
imgUrl={bannerImage3}
/>
))
.add('Component showing its own fallback image when it cannot find the fallback img specified', () => {
const bannerFileName3 = 'b2c-banner-3';
return (<ImageContainer
imgClassName="main-banner-image"
isSkuImage // THIS MUST BE TRUE!
pictureClassName="main-banner-image"
fileName={bannerFileName3}
imgUrl="https://invalidsrc.com"
/>);
})
.add('Component not showing any fallback', () => (<ImageContainer
imgClassName="main-banner-image"
isSkuImage={false} // THIS MUST BE TRUE!
pictureClassName="main-banner-image"
fileName="invalidfilename"
imgUrl="https://invalidsrc.com"
/>));
Loading