mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Add Image and ImageBackground to buildTypes and align Flow with TS defs (#49659)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/49659 Changelog: [Internal] - Added Image and ImageBackground to buildTypes and aligned Flow with TS defs Reviewed By: huntie Differential Revision: D70099485 fbshipit-source-id: 6000fc7099a4f811c451a08c4d5cf505d84ec0c9
This commit is contained in:
committed by
Facebook GitHub Bot
parent
659004f16b
commit
7856ef8409
@@ -138,7 +138,7 @@ let BaseImage: AbstractImageAndroid = React.forwardRef(
|
||||
props.loadingIndicatorSource,
|
||||
);
|
||||
|
||||
if (props.children) {
|
||||
if (props.children != null) {
|
||||
throw new Error(
|
||||
'The <Image> component cannot contain children. If you want to render content on top of the image, consider using the <ImageBackground> component or absolute positioning.',
|
||||
);
|
||||
|
||||
@@ -10,4 +10,18 @@
|
||||
|
||||
import type {Image} from './ImageTypes.flow';
|
||||
|
||||
export type {
|
||||
ImageProgressEventDataIOS,
|
||||
ImagePropsIOS,
|
||||
ImagePropsAndroid,
|
||||
ImageSourcePropType,
|
||||
ImageLoadEventData,
|
||||
ImageErrorEventData,
|
||||
ImagePropsBase,
|
||||
ImageProps,
|
||||
ImageBackgroundProps,
|
||||
} from './ImageProps';
|
||||
|
||||
export type {ImageResolvedAssetSource, ImageSize} from './ImageTypes.flow';
|
||||
|
||||
declare export default Image;
|
||||
|
||||
+97
-30
@@ -23,20 +23,36 @@ import type {
|
||||
} from '../Types/CoreEventTypes';
|
||||
import typeof Image from './Image';
|
||||
import type {ImageResizeMode} from './ImageResizeMode';
|
||||
import type {ImageSource} from './ImageSource';
|
||||
import type {ImageSource, ImageURISource} from './ImageSource';
|
||||
import type {ElementRef, Node, RefSetter} from 'react';
|
||||
|
||||
export type ImageSourcePropType = ImageSource;
|
||||
|
||||
/**
|
||||
* @see ImagePropsIOS.onProgress
|
||||
*/
|
||||
export type ImageProgressEventDataIOS = {
|
||||
loaded: number,
|
||||
total: number,
|
||||
};
|
||||
|
||||
export type ImageErrorEventData = {
|
||||
error: string,
|
||||
};
|
||||
|
||||
export type ImageLoadEventData = {
|
||||
source: {
|
||||
height: number,
|
||||
width: number,
|
||||
uri: string,
|
||||
},
|
||||
};
|
||||
|
||||
export type ImageLoadEvent = NativeSyntheticEvent<
|
||||
$ReadOnly<{
|
||||
source: $ReadOnly<{
|
||||
width: number,
|
||||
height: number,
|
||||
uri: string,
|
||||
}>,
|
||||
}>,
|
||||
$ReadOnly<ImageLoadEventData>,
|
||||
>;
|
||||
|
||||
type IOSImageProps = $ReadOnly<{
|
||||
export type ImagePropsIOS = $ReadOnly<{
|
||||
/**
|
||||
* A static image to display while loading the image source.
|
||||
*
|
||||
@@ -55,19 +71,42 @@ type IOSImageProps = $ReadOnly<{
|
||||
* See https://reactnative.dev/docs/image#onprogress
|
||||
*/
|
||||
onProgress?: ?(
|
||||
event: NativeSyntheticEvent<$ReadOnly<{loaded: number, total: number}>>,
|
||||
event: NativeSyntheticEvent<$ReadOnly<ImageProgressEventDataIOS>>,
|
||||
) => void,
|
||||
}>;
|
||||
|
||||
type AndroidImageProps = $ReadOnly<{
|
||||
loadingIndicatorSource?: ?(number | $ReadOnly<{uri: string}>),
|
||||
export type ImagePropsAndroid = $ReadOnly<{
|
||||
/**
|
||||
* similarly to `source`, this property represents the resource used to render
|
||||
* the loading indicator for the image, displayed until image is ready to be
|
||||
* displayed, typically after when it got downloaded from network.
|
||||
*/
|
||||
loadingIndicatorSource?: ?(number | $ReadOnly<ImageURISource>),
|
||||
progressiveRenderingEnabled?: ?boolean,
|
||||
fadeDuration?: ?number,
|
||||
|
||||
/**
|
||||
* The mechanism that should be used to resize the image when the image's
|
||||
* dimensions differ from the image view's dimensions. Defaults to `'auto'`.
|
||||
* See https://reactnative.dev/docs/image#resizemethod-android
|
||||
* The mechanism that should be used to resize the image when the image's dimensions
|
||||
* differ from the image view's dimensions. Defaults to `auto`.
|
||||
*
|
||||
* - `auto`: Use heuristics to pick between `resize` and `scale`.
|
||||
*
|
||||
* - `resize`: A software operation which changes the encoded image in memory before it
|
||||
* gets decoded. This should be used instead of `scale` when the image is much larger
|
||||
* than the view.
|
||||
*
|
||||
* - `scale`: The image gets drawn downscaled or upscaled. Compared to `resize`, `scale` is
|
||||
* faster (usually hardware accelerated) and produces higher quality images. This
|
||||
* should be used if the image is smaller than the view. It should also be used if the
|
||||
* image is slightly bigger than the view.
|
||||
*
|
||||
* - `none`: No sampling is performed and the image is displayed in its full resolution. This
|
||||
* should only be used in rare circumstances because it is considered unsafe as Android will
|
||||
* throw a runtime exception when trying to render images that consume too much memory.
|
||||
*
|
||||
* More details about `resize` and `scale` can be found at http://frescolib.org/docs/resizing-rotating.html.
|
||||
*
|
||||
* @platform android
|
||||
*/
|
||||
resizeMethod?: ?('auto' | 'resize' | 'scale' | 'none'),
|
||||
|
||||
@@ -81,11 +120,8 @@ type AndroidImageProps = $ReadOnly<{
|
||||
resizeMultiplier?: ?number,
|
||||
}>;
|
||||
|
||||
export type ImageProps = $ReadOnly<{
|
||||
export type ImagePropsBase = $ReadOnly<{
|
||||
...$Diff<ViewProps, $ReadOnly<{style: ?ViewStyleProp}>>,
|
||||
...IOSImageProps,
|
||||
...AndroidImageProps,
|
||||
|
||||
/**
|
||||
* When true, indicates the image is an accessibility element.
|
||||
*
|
||||
@@ -166,16 +202,15 @@ export type ImageProps = $ReadOnly<{
|
||||
* See https://reactnative.dev/docs/image#onerror
|
||||
*/
|
||||
onError?: ?(
|
||||
event: NativeSyntheticEvent<
|
||||
$ReadOnly<{
|
||||
error: string,
|
||||
}>,
|
||||
>,
|
||||
event: NativeSyntheticEvent<$ReadOnly<ImageErrorEventData>>,
|
||||
) => void,
|
||||
|
||||
/**
|
||||
* onLayout function
|
||||
*
|
||||
* Invoked on mount and layout changes with
|
||||
* `{nativeEvent: {layout: {x, y, width, height}}}`.
|
||||
*
|
||||
* {nativeEvent: { layout: {x, y, width, height} }}.
|
||||
*
|
||||
* See https://reactnative.dev/docs/image#onlayout
|
||||
*/
|
||||
@@ -206,15 +241,16 @@ export type ImageProps = $ReadOnly<{
|
||||
/**
|
||||
* The image source (either a remote URL or a local file resource).
|
||||
*
|
||||
* This prop can also contain several remote URLs, specified together with their width and height and potentially with scale/other URI arguments.
|
||||
* The native side will then choose the best uri to display based on the measured size of the image container.
|
||||
* A cache property can be added to control how networked request interacts with the local cache.
|
||||
*
|
||||
* The currently supported formats are png, jpg, jpeg, bmp, gif, webp (Android only), psd (iOS only).
|
||||
*
|
||||
* See https://reactnative.dev/docs/image#source
|
||||
*/
|
||||
source?: ?ImageSource,
|
||||
|
||||
/**
|
||||
* See https://reactnative.dev/docs/image#style
|
||||
*/
|
||||
style?: ?ImageStyleProp,
|
||||
|
||||
/**
|
||||
* A string indicating which referrer to use when fetching the resource.
|
||||
* Similar to referrerpolicy from HTML.
|
||||
@@ -236,6 +272,26 @@ export type ImageProps = $ReadOnly<{
|
||||
* Determines how to resize the image when the frame doesn't match the raw
|
||||
* image dimensions.
|
||||
*
|
||||
* 'cover': Scale the image uniformly (maintain the image's aspect ratio)
|
||||
* so that both dimensions (width and height) of the image will be equal
|
||||
* to or larger than the corresponding dimension of the view (minus padding).
|
||||
*
|
||||
* 'contain': Scale the image uniformly (maintain the image's aspect ratio)
|
||||
* so that both dimensions (width and height) of the image will be equal to
|
||||
* or less than the corresponding dimension of the view (minus padding).
|
||||
*
|
||||
* 'stretch': Scale width and height independently, This may change the
|
||||
* aspect ratio of the src.
|
||||
*
|
||||
* 'repeat': Repeat the image to cover the frame of the view.
|
||||
* The image will keep it's size and aspect ratio. (iOS only)
|
||||
*
|
||||
* '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.
|
||||
*
|
||||
* See https://reactnative.dev/docs/image#resizemode
|
||||
*/
|
||||
resizeMode?: ?ImageResizeMode,
|
||||
@@ -272,6 +328,17 @@ export type ImageProps = $ReadOnly<{
|
||||
children?: empty,
|
||||
}>;
|
||||
|
||||
export type ImageProps = $ReadOnly<{
|
||||
...ImagePropsIOS,
|
||||
...ImagePropsAndroid,
|
||||
...ImagePropsBase,
|
||||
|
||||
/**
|
||||
* See https://reactnative.dev/docs/image#style
|
||||
*/
|
||||
style?: ?ImageStyleProp,
|
||||
}>;
|
||||
|
||||
export type ImageBackgroundProps = $ReadOnly<{
|
||||
...ImageProps,
|
||||
children?: Node,
|
||||
|
||||
@@ -17,8 +17,15 @@ import typeof TextInlineImageNativeComponent from './TextInlineImageNativeCompon
|
||||
|
||||
import * as React from 'react';
|
||||
|
||||
export type ImageSize = {
|
||||
width: number,
|
||||
height: number,
|
||||
};
|
||||
|
||||
export type ImageResolvedAssetSource = ResolvedAssetSource;
|
||||
|
||||
type ImageComponentStaticsIOS = $ReadOnly<{
|
||||
getSize(uri: string): Promise<{width: number, height: number}>,
|
||||
getSize(uri: string): Promise<ImageSize>,
|
||||
getSize(
|
||||
uri: string,
|
||||
success: (width: number, height: number) => void,
|
||||
@@ -28,7 +35,7 @@ type ImageComponentStaticsIOS = $ReadOnly<{
|
||||
getSizeWithHeaders(
|
||||
uri: string,
|
||||
headers: {[string]: string, ...},
|
||||
): Promise<{width: number, height: number}>,
|
||||
): Promise<ImageSize>,
|
||||
getSizeWithHeaders(
|
||||
uri: string,
|
||||
headers: {[string]: string, ...},
|
||||
@@ -46,9 +53,12 @@ type ImageComponentStaticsIOS = $ReadOnly<{
|
||||
|
||||
queryCache(
|
||||
urls: Array<string>,
|
||||
): Promise<{[string]: 'memory' | 'disk' | 'disk/memory', ...}>,
|
||||
): Promise<{[url: string]: 'memory' | 'disk' | 'disk/memory', ...}>,
|
||||
|
||||
resolveAssetSource(source: ImageSource): ?ResolvedAssetSource,
|
||||
/**
|
||||
* @see https://reactnative.dev/docs/image#resolveassetsource
|
||||
*/
|
||||
resolveAssetSource(source: ImageSource): ?ImageResolvedAssetSource,
|
||||
}>;
|
||||
|
||||
type ImageComponentStaticsAndroid = $ReadOnly<{
|
||||
@@ -57,7 +67,7 @@ type ImageComponentStaticsAndroid = $ReadOnly<{
|
||||
}>;
|
||||
|
||||
export type AbstractImageAndroid = component(
|
||||
ref: React.RefSetter<
|
||||
ref?: React.RefSetter<
|
||||
| React.ElementRef<TextInlineImageNativeComponent>
|
||||
| React.ElementRef<ImageViewNativeComponent>,
|
||||
>,
|
||||
@@ -67,7 +77,7 @@ export type AbstractImageAndroid = component(
|
||||
export type ImageAndroid = AbstractImageAndroid & ImageComponentStaticsAndroid;
|
||||
|
||||
export type AbstractImageIOS = component(
|
||||
ref: React.RefSetter<React.ElementRef<ImageViewNativeComponent>>,
|
||||
ref?: React.RefSetter<React.ElementRef<ImageViewNativeComponent>>,
|
||||
...props: ImagePropsType
|
||||
);
|
||||
|
||||
|
||||
@@ -4470,7 +4470,19 @@ declare export function getUrlCacheBreaker(): string;
|
||||
`;
|
||||
|
||||
exports[`public API should not change unintentionally Libraries/Image/Image.js.flow 1`] = `
|
||||
"declare export default Image;
|
||||
"export type {
|
||||
ImageProgressEventDataIOS,
|
||||
ImagePropsIOS,
|
||||
ImagePropsAndroid,
|
||||
ImageSourcePropType,
|
||||
ImageLoadEventData,
|
||||
ImageErrorEventData,
|
||||
ImagePropsBase,
|
||||
ImageProps,
|
||||
ImageBackgroundProps,
|
||||
} from \\"./ImageProps\\";
|
||||
export type { ImageResolvedAssetSource, ImageSize } from \\"./ImageTypes.flow\\";
|
||||
declare export default Image;
|
||||
"
|
||||
`;
|
||||
|
||||
@@ -4515,33 +4527,40 @@ declare export function useWrapRefWithImageAttachedCallbacks(
|
||||
`;
|
||||
|
||||
exports[`public API should not change unintentionally Libraries/Image/ImageProps.js 1`] = `
|
||||
"export type ImageLoadEvent = NativeSyntheticEvent<
|
||||
$ReadOnly<{
|
||||
source: $ReadOnly<{
|
||||
width: number,
|
||||
height: number,
|
||||
uri: string,
|
||||
}>,
|
||||
}>,
|
||||
"export type ImageSourcePropType = ImageSource;
|
||||
export type ImageProgressEventDataIOS = {
|
||||
loaded: number,
|
||||
total: number,
|
||||
};
|
||||
export type ImageErrorEventData = {
|
||||
error: string,
|
||||
};
|
||||
export type ImageLoadEventData = {
|
||||
source: {
|
||||
height: number,
|
||||
width: number,
|
||||
uri: string,
|
||||
},
|
||||
};
|
||||
export type ImageLoadEvent = NativeSyntheticEvent<
|
||||
$ReadOnly<ImageLoadEventData>,
|
||||
>;
|
||||
type IOSImageProps = $ReadOnly<{
|
||||
export type ImagePropsIOS = $ReadOnly<{
|
||||
defaultSource?: ?ImageSource,
|
||||
onPartialLoad?: ?() => void,
|
||||
onProgress?: ?(
|
||||
event: NativeSyntheticEvent<$ReadOnly<{ loaded: number, total: number }>>
|
||||
event: NativeSyntheticEvent<$ReadOnly<ImageProgressEventDataIOS>>
|
||||
) => void,
|
||||
}>;
|
||||
type AndroidImageProps = $ReadOnly<{
|
||||
loadingIndicatorSource?: ?(number | $ReadOnly<{ uri: string }>),
|
||||
export type ImagePropsAndroid = $ReadOnly<{
|
||||
loadingIndicatorSource?: ?(number | $ReadOnly<ImageURISource>),
|
||||
progressiveRenderingEnabled?: ?boolean,
|
||||
fadeDuration?: ?number,
|
||||
resizeMethod?: ?(\\"auto\\" | \\"resize\\" | \\"scale\\" | \\"none\\"),
|
||||
resizeMultiplier?: ?number,
|
||||
}>;
|
||||
export type ImageProps = $ReadOnly<{
|
||||
export type ImagePropsBase = $ReadOnly<{
|
||||
...$Diff<ViewProps, $ReadOnly<{ style: ?ViewStyleProp }>>,
|
||||
...IOSImageProps,
|
||||
...AndroidImageProps,
|
||||
accessible?: ?boolean,
|
||||
internal_analyticTag?: ?string,
|
||||
accessibilityLabel?: ?Stringish,
|
||||
@@ -4554,18 +4573,13 @@ export type ImageProps = $ReadOnly<{
|
||||
height?: number,
|
||||
width?: number,
|
||||
onError?: ?(
|
||||
event: NativeSyntheticEvent<
|
||||
$ReadOnly<{
|
||||
error: string,
|
||||
}>,
|
||||
>
|
||||
event: NativeSyntheticEvent<$ReadOnly<ImageErrorEventData>>
|
||||
) => void,
|
||||
onLayout?: ?(event: LayoutChangeEvent) => mixed,
|
||||
onLoad?: ?(event: ImageLoadEvent) => void,
|
||||
onLoadEnd?: ?() => void,
|
||||
onLoadStart?: ?() => void,
|
||||
source?: ?ImageSource,
|
||||
style?: ?ImageStyleProp,
|
||||
referrerPolicy?: ?(
|
||||
| \\"no-referrer\\"
|
||||
| \\"no-referrer-when-downgrade\\"
|
||||
@@ -4583,6 +4597,12 @@ export type ImageProps = $ReadOnly<{
|
||||
srcSet?: ?string,
|
||||
children?: empty,
|
||||
}>;
|
||||
export type ImageProps = $ReadOnly<{
|
||||
...ImagePropsIOS,
|
||||
...ImagePropsAndroid,
|
||||
...ImagePropsBase,
|
||||
style?: ?ImageStyleProp,
|
||||
}>;
|
||||
export type ImageBackgroundProps = $ReadOnly<{
|
||||
...ImageProps,
|
||||
children?: Node,
|
||||
@@ -4646,8 +4666,13 @@ exports[`public API should not change unintentionally Libraries/Image/ImageSourc
|
||||
`;
|
||||
|
||||
exports[`public API should not change unintentionally Libraries/Image/ImageTypes.flow.js 1`] = `
|
||||
"type ImageComponentStaticsIOS = $ReadOnly<{
|
||||
getSize(uri: string): Promise<{ width: number, height: number }>,
|
||||
"export type ImageSize = {
|
||||
width: number,
|
||||
height: number,
|
||||
};
|
||||
export type ImageResolvedAssetSource = ResolvedAssetSource;
|
||||
type ImageComponentStaticsIOS = $ReadOnly<{
|
||||
getSize(uri: string): Promise<ImageSize>,
|
||||
getSize(
|
||||
uri: string,
|
||||
success: (width: number, height: number) => void,
|
||||
@@ -4656,7 +4681,7 @@ exports[`public API should not change unintentionally Libraries/Image/ImageTypes
|
||||
getSizeWithHeaders(
|
||||
uri: string,
|
||||
headers: { [string]: string, ... }
|
||||
): Promise<{ width: number, height: number }>,
|
||||
): Promise<ImageSize>,
|
||||
getSizeWithHeaders(
|
||||
uri: string,
|
||||
headers: { [string]: string, ... },
|
||||
@@ -4671,15 +4696,15 @@ exports[`public API should not change unintentionally Libraries/Image/ImageTypes
|
||||
): Promise<boolean>,
|
||||
queryCache(
|
||||
urls: Array<string>
|
||||
): Promise<{ [string]: \\"memory\\" | \\"disk\\" | \\"disk/memory\\", ... }>,
|
||||
resolveAssetSource(source: ImageSource): ?ResolvedAssetSource,
|
||||
): Promise<{ [url: string]: \\"memory\\" | \\"disk\\" | \\"disk/memory\\", ... }>,
|
||||
resolveAssetSource(source: ImageSource): ?ImageResolvedAssetSource,
|
||||
}>;
|
||||
type ImageComponentStaticsAndroid = $ReadOnly<{
|
||||
...ImageComponentStaticsIOS,
|
||||
abortPrefetch(requestId: number): void,
|
||||
}>;
|
||||
export type AbstractImageAndroid = component(
|
||||
ref: React.RefSetter<
|
||||
ref?: React.RefSetter<
|
||||
| React.ElementRef<TextInlineImageNativeComponent>
|
||||
| React.ElementRef<ImageViewNativeComponent>,
|
||||
>,
|
||||
@@ -4687,7 +4712,7 @@ export type AbstractImageAndroid = component(
|
||||
);
|
||||
export type ImageAndroid = AbstractImageAndroid & ImageComponentStaticsAndroid;
|
||||
export type AbstractImageIOS = component(
|
||||
ref: React.RefSetter<React.ElementRef<ImageViewNativeComponent>>,
|
||||
ref?: React.RefSetter<React.ElementRef<ImageViewNativeComponent>>,
|
||||
...props: ImagePropsType
|
||||
);
|
||||
export type ImageIOS = AbstractImageIOS & ImageComponentStaticsIOS;
|
||||
|
||||
@@ -1344,8 +1344,8 @@ export class ImageTest extends React.Component {
|
||||
const uri =
|
||||
'https://seeklogo.com/images/T/typescript-logo-B29A3F462D-seeklogo.com.png';
|
||||
const headers = {Authorization: 'Bearer test'};
|
||||
const image: ImageResolvedAssetSource = Image.resolveAssetSource({uri});
|
||||
console.log(image.width, image.height, image.scale, image.uri);
|
||||
const image = Image.resolveAssetSource({uri});
|
||||
console.log(image?.width, image?.height, image?.scale, image?.uri);
|
||||
|
||||
Image.queryCache &&
|
||||
Image.queryCache([uri]).then(({[uri]: status}) => {
|
||||
@@ -1380,14 +1380,14 @@ export class ImageTest extends React.Component {
|
||||
Image.prefetch(uri); // $ExpectType Promise<boolean>
|
||||
}
|
||||
|
||||
handleOnLoad = (e: NativeSyntheticEvent<ImageLoadEventData>) => {
|
||||
handleOnLoad = (e: NativeSyntheticEvent<Readonly<ImageLoadEventData>>) => {
|
||||
testNativeSyntheticEvent(e);
|
||||
console.log('height:', e.nativeEvent.source.height);
|
||||
console.log('width:', e.nativeEvent.source.width);
|
||||
console.log('uri:', e.nativeEvent.source.uri);
|
||||
};
|
||||
|
||||
handleOnError = (e: NativeSyntheticEvent<ImageErrorEventData>) => {
|
||||
handleOnError = (e: NativeSyntheticEvent<Readonly<ImageErrorEventData>>) => {
|
||||
testNativeSyntheticEvent(e);
|
||||
console.log('error:', e.nativeEvent.error);
|
||||
};
|
||||
|
||||
@@ -80,6 +80,8 @@ const ENTRY_POINTS = [
|
||||
'packages/react-native/Libraries/Components/Switch/Switch.js',
|
||||
'packages/react-native/Libraries/Components/StatusBar/StatusBar.js',
|
||||
'packages/react-native/Libraries/Components/RefreshControl/RefreshControl.js',
|
||||
'packages/react-native/Libraries/Image/Image.js.flow',
|
||||
'packages/react-native/Libraries/Image/ImageBackground.js',
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user