Skip to content
Closed
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
2 changes: 2 additions & 0 deletions packages/react-native/Libraries/Image/Image.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ export interface ImagePropsBase
* 'center': Scale the image down so that it is completely visible,
* if bigger than the area of the view.
* The image will not be scaled up.
*
* 'none': Do not resize the image. The image will be displayed at its intrinsic size.
*/
resizeMode?: ImageResizeMode | undefined;

Expand Down
9 changes: 8 additions & 1 deletion packages/react-native/Libraries/Image/ImageProps.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,14 @@ export type ImageProps = $ReadOnly<{|
*
* See https://reactnative.dev/docs/image#resizemode
*/
resizeMode?: ?('cover' | 'contain' | 'stretch' | 'repeat' | 'center'),
resizeMode?: ?(
| 'cover'
| 'contain'
| 'stretch'
| 'repeat'
| 'center'
| 'none'
),

/**
* A unique identifier for this element to be used in UI Automation
Expand Down
9 changes: 8 additions & 1 deletion packages/react-native/Libraries/Image/ImageResizeMode.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ export type ImageResizeMode =
| 'contain'
| 'stretch'
| 'repeat'
| 'center';
| 'center'
| 'none';

/**
* @see ImageResizeMode.js
Expand Down Expand Up @@ -46,4 +47,10 @@ export interface ImageResizeModeStatic {
* image will keep it's size and aspect ratio.
*/
repeat: ImageResizeMode;

/**
* none - The image will be displayed at its intrinsic size, which means the
* image will not be scaled up or down.
*/
none: ImageResizeMode;
}
5 changes: 4 additions & 1 deletion packages/react-native/Libraries/Image/ImageResizeMode.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,7 @@ export type ImageResizeMode =

// Resize by stretching it to fill the entire frame of the view without
// clipping. This may change the aspect ratio of the image, distorting it.
| 'stretch';
| 'stretch'

// The image will not be resized at all.
| 'none';
9 changes: 8 additions & 1 deletion packages/react-native/Libraries/Image/ImageUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,20 @@
* @format
*/

type ResizeMode = 'cover' | 'contain' | 'stretch' | 'repeat' | 'center';
type ResizeMode =
| 'cover'
| 'contain'
| 'stretch'
| 'repeat'
| 'center'
| 'none';

const objectFitMap: {[string]: ResizeMode} = {
contain: 'contain',
cover: 'cover',
fill: 'stretch',
'scale-down': 'contain',
none: 'none',
};

export function convertObjectFitToResizeMode(objectFit: ?string): ?ResizeMode {
Expand Down
2 changes: 2 additions & 0 deletions packages/react-native/Libraries/Image/RCTImageUtils.mm
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ CGRect RCTTargetRect(CGSize sourceSize, CGSize destSize, CGFloat destScale, RCTR
switch (resizeMode) {
case RCTResizeModeStretch:
case RCTResizeModeRepeat:
case RCTResizeModeNone:

return (CGRect){CGPointZero, RCTCeilSize(destSize, destScale)};

Expand Down Expand Up @@ -249,6 +250,7 @@ BOOL RCTUpscalingRequired(

case RCTResizeModeRepeat:
case RCTResizeModeCenter:
case RCTResizeModeNone:

return NO;
}
Expand Down
5 changes: 4 additions & 1 deletion packages/react-native/Libraries/Image/RCTResizeMode.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ typedef NS_ENUM(NSInteger, RCTResizeMode) {
RCTResizeModeStretch = UIViewContentModeScaleToFill,
RCTResizeModeCenter = UIViewContentModeCenter,
RCTResizeModeRepeat = -1, // Use negative values to avoid conflicts with iOS enum values.
RCTResizeModeNone = UIViewContentModeTopLeft,
};

static inline RCTResizeMode RCTResizeModeFromUIViewContentMode(UIViewContentMode mode)
Expand All @@ -30,12 +31,14 @@ static inline RCTResizeMode RCTResizeModeFromUIViewContentMode(UIViewContentMode
case UIViewContentModeCenter:
return RCTResizeModeCenter;
break;
case UIViewContentModeTopLeft:
return RCTResizeModeNone;
break;
case UIViewContentModeRedraw:
case UIViewContentModeTop:
case UIViewContentModeBottom:
case UIViewContentModeLeft:
case UIViewContentModeRight:
case UIViewContentModeTopLeft:
case UIViewContentModeTopRight:
case UIViewContentModeBottomLeft:
case UIViewContentModeBottomRight:
Expand Down
1 change: 1 addition & 0 deletions packages/react-native/Libraries/Image/RCTResizeMode.mm
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ @implementation RCTConvert (RCTResizeMode)
@"stretch" : @(RCTResizeModeStretch),
@"center" : @(RCTResizeModeCenter),
@"repeat" : @(RCTResizeModeRepeat),
@"none" : @(RCTResizeModeNone),
}),
RCTResizeModeStretch,
integerValue)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,6 @@ export interface ImageStyle extends FlexStyle, ShadowStyleIOS, TransformsStyle {
overlayColor?: ColorValue | undefined;
tintColor?: ColorValue | undefined;
opacity?: AnimatableNumericValue | undefined;
objectFit?: 'cover' | 'contain' | 'fill' | 'scale-down' | undefined;
objectFit?: 'cover' | 'contain' | 'fill' | 'scale-down' | 'none' | undefined;
cursor?: CursorValue | undefined;
}
4 changes: 2 additions & 2 deletions packages/react-native/Libraries/StyleSheet/StyleSheetTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -942,7 +942,7 @@ export type ____TextStyle_Internal = $ReadOnly<{
export type ____ImageStyle_InternalCore = $ReadOnly<{
...$Exact<____ViewStyle_Internal>,
resizeMode?: 'contain' | 'cover' | 'stretch' | 'center' | 'repeat',
objectFit?: 'cover' | 'contain' | 'fill' | 'scale-down',
objectFit?: 'cover' | 'contain' | 'fill' | 'scale-down' | 'none',
tintColor?: ____ColorValue_Internal,
overlayColor?: string,
}>;
Expand All @@ -955,7 +955,7 @@ export type ____ImageStyle_Internal = $ReadOnly<{
export type ____DangerouslyImpreciseStyle_InternalCore = $ReadOnly<{
...$Exact<____TextStyle_Internal>,
resizeMode?: 'contain' | 'cover' | 'stretch' | 'center' | 'repeat',
objectFit?: 'cover' | 'contain' | 'fill' | 'scale-down',
objectFit?: 'cover' | 'contain' | 'fill' | 'scale-down' | 'none',
tintColor?: ____ColorValue_Internal,
overlayColor?: string,
}>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4872,7 +4872,14 @@ export type ImageProps = $ReadOnly<{|
| \\"strict-origin-when-cross-origin\\"
| \\"unsafe-url\\"
),
resizeMode?: ?(\\"cover\\" | \\"contain\\" | \\"stretch\\" | \\"repeat\\" | \\"center\\"),
resizeMode?: ?(
| \\"cover\\"
| \\"contain\\"
| \\"stretch\\"
| \\"repeat\\"
| \\"center\\"
| \\"none\\"
),
testID?: ?string,
tintColor?: ColorValue,
src?: ?string,
Expand All @@ -4895,7 +4902,8 @@ exports[`public API should not change unintentionally Libraries/Image/ImageResiz
| \\"contain\\"
| \\"cover\\"
| \\"repeat\\"
| \\"stretch\\";
| \\"stretch\\"
| \\"none\\";
"
`;

Expand Down Expand Up @@ -4992,7 +5000,13 @@ export type { ImageProps } from \\"./ImageProps\\";
`;

exports[`public API should not change unintentionally Libraries/Image/ImageUtils.js 1`] = `
"type ResizeMode = \\"cover\\" | \\"contain\\" | \\"stretch\\" | \\"repeat\\" | \\"center\\";
"type ResizeMode =
| \\"cover\\"
| \\"contain\\"
| \\"stretch\\"
| \\"repeat\\"
| \\"center\\"
| \\"none\\";
declare export function convertObjectFitToResizeMode(
objectFit: ?string
): ?ResizeMode;
Expand Down Expand Up @@ -8262,7 +8276,7 @@ export type ____TextStyle_Internal = $ReadOnly<{
export type ____ImageStyle_InternalCore = $ReadOnly<{
...$Exact<____ViewStyle_Internal>,
resizeMode?: \\"contain\\" | \\"cover\\" | \\"stretch\\" | \\"center\\" | \\"repeat\\",
objectFit?: \\"cover\\" | \\"contain\\" | \\"fill\\" | \\"scale-down\\",
objectFit?: \\"cover\\" | \\"contain\\" | \\"fill\\" | \\"scale-down\\" | \\"none\\",
tintColor?: ____ColorValue_Internal,
overlayColor?: string,
}>;
Expand All @@ -8273,7 +8287,7 @@ export type ____ImageStyle_Internal = $ReadOnly<{
export type ____DangerouslyImpreciseStyle_InternalCore = $ReadOnly<{
...$Exact<____TextStyle_Internal>,
resizeMode?: \\"contain\\" | \\"cover\\" | \\"stretch\\" | \\"center\\" | \\"repeat\\",
objectFit?: \\"cover\\" | \\"contain\\" | \\"fill\\" | \\"scale-down\\",
objectFit?: \\"cover\\" | \\"contain\\" | \\"fill\\" | \\"scale-down\\" | \\"none\\",
tintColor?: ____ColorValue_Internal,
overlayColor?: string,
}>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public object ImageResizeMode {
private const val RESIZE_MODE_STRETCH = "stretch"
private const val RESIZE_MODE_CENTER = "center"
private const val RESIZE_MODE_REPEAT = "repeat"
private const val RESIZE_MODE_NONE = "none"

/** Converts JS resize modes into `ScalingUtils.ScaleType`. See `ImageResizeMode.js`. */
@JvmStatic
Expand All @@ -30,6 +31,7 @@ public object ImageResizeMode {
RESIZE_MODE_CENTER -> return ScalingUtils.ScaleType.CENTER_INSIDE
// Handled via a combination of ScaleType and TileMode
RESIZE_MODE_REPEAT -> return ScaleTypeStartInside.INSTANCE
RESIZE_MODE_NONE -> return ScaleTypeStartInside.INSTANCE
}

if (resizeModeValue != null) {
Expand All @@ -45,7 +47,8 @@ public object ImageResizeMode {
if (RESIZE_MODE_CONTAIN == resizeModeValue ||
RESIZE_MODE_COVER == resizeModeValue ||
RESIZE_MODE_STRETCH == resizeModeValue ||
RESIZE_MODE_CENTER == resizeModeValue) {
RESIZE_MODE_CENTER == resizeModeValue ||
RESIZE_MODE_NONE == resizeModeValue) {
return TileMode.CLAMP
}
if (RESIZE_MODE_REPEAT == resizeModeValue) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class ImageResizeModeTest {
.isEqualTo(ScalingUtils.ScaleType.FIT_XY)
Assertions.assertThat(ImageResizeMode.toScaleType("center"))
.isEqualTo(ScalingUtils.ScaleType.CENTER_INSIDE)
Assertions.assertThat(ImageResizeMode.toScaleType("none"))
.isEqualTo(ScaleTypeStartInside.INSTANCE)

// No resizeMode set
Assertions.assertThat(ImageResizeMode.defaultValue())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ inline void fromRawValue(
result = ImageResizeMode::Center;
} else if (stringValue == "repeat") {
result = ImageResizeMode::Repeat;
} else if (stringValue == "none") {
result = ImageResizeMode::None;
} else {
LOG(ERROR) << "Unsupported ImageResizeMode value: " << stringValue;
react_native_expect(false);
Expand All @@ -168,6 +170,8 @@ inline std::string toString(const ImageResizeMode& value) {
return "center";
case ImageResizeMode::Repeat:
return "repeat";
case ImageResizeMode::None:
return "none";
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ inline static UIViewContentMode RCTContentModeFromImageResizeMode(facebook::reac
// Repeat resize mode is handled by the UIImage. Use scale to fill
// so the repeated image fills the UIImageView.
return UIViewContentModeScaleToFill;
case facebook::react::ImageResizeMode::None:
return UIViewContentModeTopLeft;
}
}

Expand All @@ -42,6 +44,8 @@ inline std::string toString(const facebook::react::ImageResizeMode &value)
return "center";
case facebook::react::ImageResizeMode::Repeat:
return "repeat";
case facebook::react::ImageResizeMode::None:
return "none";
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ enum class ImageResizeMode {
Stretch,
Center,
Repeat,
None,
};

class ImageErrorInfo {
Expand Down
26 changes: 26 additions & 0 deletions packages/rn-tester/js/examples/Image/ImageExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,9 @@ const styles = StyleSheet.create({
objectFitScaleDown: {
objectFit: 'scale-down',
},
objectFitNone: {
objectFit: 'none',
},
imageInBundle: {
borderColor: 'yellow',
borderWidth: 4,
Expand Down Expand Up @@ -1391,6 +1394,17 @@ exports.examples = [
/>
</View>
</View>
<View style={styles.horizontal}>
<View>
<RNTesterText style={styles.resizeModeText}>
None
</RNTesterText>
<Image
style={[styles.resizeMode, styles.objectFitNone]}
source={image}
/>
</View>
</View>
</View>
);
})}
Expand Down Expand Up @@ -1462,6 +1476,18 @@ exports.examples = [
/>
</View>
</View>
<View style={styles.horizontal}>
<View>
<RNTesterText style={styles.resizeModeText}>
None
</RNTesterText>
<Image
style={styles.resizeMode}
resizeMode="none"
source={image}
/>
</View>
</View>
</View>
);
})}
Expand Down
Loading