1import React, { useEffect, Ref } from 'react'; 2 3import ColorTintFilter, { getTintColorStyle } from './ColorTintFilter'; 4import { ImageWrapperProps } from './ImageWrapper.types'; 5import { getImageWrapperEventHandler } from './getImageWrapperEventHandler'; 6import { useHeaders, useImageHashes } from './hooks'; 7import { absoluteFilledPosition, getObjectPositionFromContentPositionObject } from './positioning'; 8import { SrcSetSource } from './useSourceSelection'; 9import { ImageNativeProps, ImageSource } from '../Image.types'; 10 11function getFetchPriorityFromImagePriority(priority: ImageNativeProps['priority'] = 'normal') { 12 return priority && ['low', 'high'].includes(priority) ? priority : 'auto'; 13} 14 15function getImgPropsFromSource(source: ImageSource | SrcSetSource | null | undefined) { 16 if (source && 'srcset' in source) { 17 return { 18 srcSet: source.srcset, 19 sizes: source.sizes, 20 }; 21 } 22 return {}; 23} 24 25const ImageWrapper = React.forwardRef( 26 ( 27 { 28 source, 29 events, 30 contentPosition, 31 hashPlaceholderContentPosition, 32 priority, 33 style, 34 hashPlaceholderStyle, 35 tintColor, 36 className, 37 accessibilityLabel, 38 cachePolicy, 39 ...props 40 }: ImageWrapperProps, 41 ref: Ref<HTMLImageElement> 42 ) => { 43 useEffect(() => { 44 events?.onMount?.forEach((e) => e?.()); 45 }, []); 46 47 // Thumbhash uri always has to start with 'thumbhash:/' 48 const { resolvedSource, isImageHash } = useImageHashes(source); 49 50 const objectPosition = getObjectPositionFromContentPositionObject( 51 isImageHash ? hashPlaceholderContentPosition : contentPosition 52 ); 53 54 const sourceWithHeaders = useHeaders(resolvedSource, cachePolicy, events?.onError); 55 if (!sourceWithHeaders) { 56 return null; 57 } 58 return ( 59 <> 60 <ColorTintFilter tintColor={tintColor} /> 61 <img 62 ref={ref} 63 alt={accessibilityLabel} 64 className={className} 65 src={sourceWithHeaders?.uri || undefined} 66 key={source?.uri} 67 style={{ 68 objectPosition, 69 ...absoluteFilledPosition, 70 ...getTintColorStyle(tintColor), 71 ...(isImageHash ? hashPlaceholderStyle : {}), 72 ...style, 73 }} 74 // @ts-ignore 75 // eslint-disable-next-line react/no-unknown-property 76 fetchpriority={getFetchPriorityFromImagePriority(priority || 'normal')} 77 {...getImageWrapperEventHandler(events, sourceWithHeaders)} 78 {...getImgPropsFromSource(source)} 79 {...props} 80 /> 81 </> 82 ); 83 } 84); 85 86export default ImageWrapper; 87