Skip to content
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
5 changes: 5 additions & 0 deletions .changeset/gorgeous-tomatoes-push.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@shopify/polaris': patch
---

Added support for ref to `Image` to handle image load with `EmptyState`
13 changes: 8 additions & 5 deletions polaris-react/src/components/EmptyState/EmptyState.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, {useState, useCallback} from 'react';
import React, {useState, useRef, useEffect} from 'react';

import {classNames} from '../../utilities/css';
import type {ComplexAction} from '../../types';
Expand Down Expand Up @@ -47,9 +47,10 @@ export function EmptyState({
footerContent,
}: EmptyStateProps) {
const [imageLoaded, setImageLoaded] = useState<boolean>(false);
const imageRef = useRef<HTMLImageElement>(null);

const handleLoad = useCallback(() => {
setImageLoaded(true);
useEffect(() => {
if (imageRef.current?.complete) setImageLoaded(true);
}, []);

const imageClassNames = classNames(
Expand All @@ -62,22 +63,24 @@ export function EmptyState({
<Image
alt=""
role="presentation"
ref={imageRef}
source={largeImage}
className={imageClassNames}
sourceSet={[
{source: image, descriptor: '568w'},
{source: largeImage, descriptor: '1136w'},
]}
sizes="(max-width: 568px) 60vw"
onLoad={handleLoad}
onLoad={() => setImageLoaded(true)}
/>
) : (
<Image
alt=""
role="presentation"
ref={imageRef}
className={imageClassNames}
source={image}
onLoad={handleLoad}
onLoad={() => setImageLoaded(true)}
/>
);

Expand Down
59 changes: 29 additions & 30 deletions polaris-react/src/components/Image/Image.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, {useCallback} from 'react';
import React, {useCallback, forwardRef} from 'react';

interface SourceSet {
source: string;
Expand All @@ -16,34 +16,33 @@ export interface ImageProps extends React.HTMLProps<HTMLImageElement> {
onError?(): void;
}

export function Image({
alt,
sourceSet,
source,
crossOrigin,
onLoad,
className,
...rest
}: ImageProps) {
const finalSourceSet = sourceSet
? sourceSet
.map(({source: subSource, descriptor}) => `${subSource} ${descriptor}`)
.join(',')
: null;
export const Image = forwardRef<HTMLImageElement, ImageProps>(
({alt, sourceSet, source, crossOrigin, onLoad, className, ...rest}, ref) => {
const finalSourceSet = sourceSet
? sourceSet
.map(
({source: subSource, descriptor}) => `${subSource} ${descriptor}`,
)
.join(',')
: null;

const handleLoad = useCallback(() => {
if (onLoad) onLoad();
}, [onLoad]);
const handleLoad = useCallback(() => {
if (onLoad) onLoad();
}, [onLoad]);

return (
<img
alt={alt}
src={source}
crossOrigin={crossOrigin}
className={className}
onLoad={handleLoad}
{...(finalSourceSet ? {srcSet: finalSourceSet} : {})}
{...rest}
/>
);
}
return (
<img
ref={ref}
alt={alt}
src={source}
crossOrigin={crossOrigin}
className={className}
onLoad={handleLoad}
{...(finalSourceSet ? {srcSet: finalSourceSet} : {})}
{...rest}
/>
);
},
);

Image.displayName = 'Image';