diff --git a/packages/render-html/src/elements/IMGElementContentLoading.tsx b/packages/render-html/src/elements/IMGElementContentLoading.tsx index c1f830f37..07731de42 100644 --- a/packages/render-html/src/elements/IMGElementContentLoading.tsx +++ b/packages/render-html/src/elements/IMGElementContentLoading.tsx @@ -8,17 +8,14 @@ import { IMGElementStateLoading } from './img-types'; export default function IMGElementContentLoading({ dimensions, alt, - testID, children -}: PropsWithChildren< - IMGElementStateLoading & { testID?: string } ->): ReactElement { +}: PropsWithChildren): ReactElement { return ( + testID="image-loading"> {children} ); diff --git a/packages/render-html/src/elements/__tests__/IMGElement.test.tsx b/packages/render-html/src/elements/__tests__/IMGElement.test.tsx index 732a3962a..0d011a73d 100644 --- a/packages/render-html/src/elements/__tests__/IMGElement.test.tsx +++ b/packages/render-html/src/elements/__tests__/IMGElement.test.tsx @@ -104,6 +104,44 @@ describe('IMGElement', () => { expect(image).toBeTruthy(); expect(StyleSheet.flatten(image.props.style)).toMatchObject(style); }); + it('should combine width with aspectRatio', async () => { + const source = { uri: 'http://via.placeholder.com/640' }; + const dimensions = { + width: 320 + }; + const { findByTestId } = render( + + ); + const image = await findByTestId('image-success'); + expect(image).toBeTruthy(); + expect(StyleSheet.flatten(image.props.style)).toMatchObject({ + width: 320, + height: 160 + }); + }); + it('should combine height with aspectRatio', async () => { + const source = { uri: 'http://via.placeholder.com/640' }; + const dimensions = { + height: 160 + }; + const { findByTestId } = render( + + ); + const image = await findByTestId('image-success'); + expect(image).toBeTruthy(); + expect(StyleSheet.flatten(image.props.style)).toMatchObject({ + width: 320, + height: 160 + }); + }); it('should scale down required dimensions to contentWidth prop when appropriate', async () => { const source = { uri: 'http://via.placeholder.com/640x360' }; const style = { diff --git a/packages/render-html/src/elements/getDimensionsWithAspectRatio.ts b/packages/render-html/src/elements/getDimensionsWithAspectRatio.ts new file mode 100644 index 000000000..521760e73 --- /dev/null +++ b/packages/render-html/src/elements/getDimensionsWithAspectRatio.ts @@ -0,0 +1,10 @@ +export default function getDimensionsWithAspectRatio( + width: number | null, + height: number | null, + aspectRatio: number | undefined +) { + return { + width: width ?? (aspectRatio && height ? height * aspectRatio : null), + height: height ?? (aspectRatio && width ? width / aspectRatio : null) + }; +} diff --git a/packages/render-html/src/elements/useImageNaturalDimensions.ts b/packages/render-html/src/elements/useImageNaturalDimensions.ts index 22dc54a4e..4efb78e49 100644 --- a/packages/render-html/src/elements/useImageNaturalDimensions.ts +++ b/packages/render-html/src/elements/useImageNaturalDimensions.ts @@ -1,6 +1,7 @@ import { useState, useMemo, useEffect } from 'react'; import { StyleSheet } from 'react-native'; import { ImageDimensions } from '../shared-types'; +import getDimensionsWithAspectRatio from './getDimensionsWithAspectRatio'; import { UseIMGElementStateProps } from './img-types'; interface IncompleteImageDimensions { @@ -63,10 +64,11 @@ function deriveSpecifiedDimensionsFromProps({ const heightProp = normalizeSize(height, normalizeOptionsHeight); const styleWidth = normalizeSize(flatStyle.width, normalizeOptionsWidth); const styleHeight = normalizeSize(flatStyle.height, normalizeOptionsHeight); - return { - width: styleWidth ?? widthProp, - height: styleHeight ?? heightProp - }; + return getDimensionsWithAspectRatio( + styleWidth ?? widthProp, + styleHeight ?? heightProp, + flatStyle.aspectRatio + ); } export default function useImageNaturalDimensions<