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<