Skip to content

Commit

Permalink
[EmptyState/Image] Handle image load with ref
Browse files Browse the repository at this point in the history
  • Loading branch information
laurkim committed Apr 10, 2024
1 parent 4745e68 commit af8dd77
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 35 deletions.
24 changes: 19 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, useCallback, useRef, useEffect} from 'react';

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

const handleLoad = useCallback(() => {
setImageLoaded(true);
const handleLoad = useCallback((image: HTMLImageElement) => {
if (image.complete) {
setImageLoaded(true);
return;
}

requestAnimationFrame(() => handleLoad(image));
}, []);

useEffect(() => {
const imageElement = imageRef.current;

if (imageElement) {
handleLoad(imageElement);
}
}, [handleLoad]);

const imageClassNames = classNames(
styles.Image,
imageLoaded && styles.loaded,
Expand All @@ -62,22 +76,22 @@ 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}
/>
) : (
<Image
alt=""
role="presentation"
ref={imageRef}
className={imageClassNames}
source={image}
onLoad={handleLoad}
/>
);

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';

0 comments on commit af8dd77

Please sign in to comment.