Skip to content

Typescript/image #775

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 24, 2020
Merged
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
74 changes: 74 additions & 0 deletions generatedTypes/components/image/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import React, { PureComponent } from 'react';
import { ImageProps as RNImageProps } from 'react-native';
import { ForwardRefInjectedProps } from '../../commons/new';
import { OverlayTypeType } from '../overlay';
declare type ImageProps = RNImageProps & {
/**
* custom source transform handler for manipulating the image source (great for size control)
*/
sourceTransformer?: Function;
/**
* if provided image source will be driven from asset name
*/
assetName?: string;
/**
* the asset group, default is "icons"
*/
assetGroup?: string;
/**
* the asset tint
*/
tintColor?: string;
/**
* whether the image should flip horizontally on RTL locals
*/
supportRTL?: boolean;
/**
* Show image as a cover, full width, image (according to aspect ratio, default: 16:8)
*/
cover?: boolean;
/**
* The aspect ratio for the image
*/
aspectRatio?: number;
/**
* The type of overly to place on top of the image. Note: the image MUST have proper size, see examples in:
* https://github.com/wix/react-native-ui-lib/blob/master/demo/src/screens/componentScreens/OverlaysScreen.js
*/
overlayType?: OverlayTypeType;
/**
* Pass a custom color for the overlay
*/
overlayColor?: string;
/**
* Render an overlay with custom content
*/
customOverlayContent?: JSX.Element;
};
declare type Props = ImageProps & ForwardRefInjectedProps;
/**
* @description: Image wrapper with extra functionality like source transform and assets support
* @extends: Image
* @extendslink: https://facebook.github.io/react-native/docs/image.html
*/
declare class Image extends PureComponent<Props> {
static displayName: string;
static defaultProps: {
assetGroup: string;
};
static overlayTypes: {
VERTICAL: string;
TOP: string;
BOTTOM: string;
SOLID: string;
};
sourceTransformer?: Function;
constructor(props: Props);
isGif(): boolean | undefined;
shouldUseImageBackground(): boolean;
getImageSource(): any;
render(): JSX.Element;
}
export { Image };
declare const _default: React.ComponentType<ImageProps>;
export default _default;
59 changes: 59 additions & 0 deletions generatedTypes/components/overlay/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { PureComponent } from 'react';
import { ImageSourcePropType } from 'react-native';
declare const OVERLY_TYPES: {
VERTICAL: string;
TOP: string;
BOTTOM: string;
SOLID: string;
};
export declare type OverlayTypeType = typeof OVERLY_TYPES[keyof typeof OVERLY_TYPES];
export declare type OverlayTypes = {
/**
* The type of overlay to set on top of the image
*/
type?: OverlayTypeType;
/**
* The overlay color
*/
color?: string;
/**
* Custom overlay content to be rendered on top of the image
*/
customContent?: JSX.Element;
};
/**
* @description: Overlay view with types (default, top, bottom, solid)
* @extends: Image
* @extendsLink: https://facebook.github.io/react-native/docs/image
*/
declare class Overlay extends PureComponent<OverlayTypes> {
static displayName: string;
static overlayTypes: {
VERTICAL: string;
TOP: string;
BOTTOM: string;
SOLID: string;
};
getStyleByType(type?: string | undefined): ("" | {
backgroundColor: string;
} | undefined)[] | ("" | {
bottom: undefined;
top: number;
height: string;
} | {
tintColor: string;
} | undefined)[] | ("" | {
bottom: number;
top: undefined;
height: string;
transform: {
scaleY: number;
}[];
} | {
tintColor: string;
} | undefined)[] | undefined;
renderCustomContent: () => JSX.Element;
renderImage: (style: any, source: ImageSourcePropType) => JSX.Element;
render(): JSX.Element;
}
export default Overlay;
3 changes: 2 additions & 1 deletion generatedTypes/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export {default as View} from './components/view';
export {default as Text} from './components/text';
export {default as TouchableOpacity} from './components/touchableOpacity';
export {default as Button} from './components/button';
export {default as Image} from './components/image';
export {default as Overlay} from './components/overlay';
export {default as RadioButton} from './components/radioButton/RadioButton';
export {default as RadioGroup} from './components/radioButton/RadioGroup';

Expand All @@ -25,7 +27,6 @@ export {
FloatingButton,
FeatureHighlight,
Hint,
Image,
BaseInput,
TextArea,
MaskedInput,
Expand Down
26 changes: 14 additions & 12 deletions src/components/image/__tests__/index.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Image from '../index';
import {Image} from '../index';
import {ThemeManager} from '../../../style';
import Assets from '../../../assets';

Expand All @@ -19,17 +19,19 @@ describe('Image', () => {
expect(uut.getImageSource()).toBe(2);
});

it('should return transformed source prop, according to sourceTransform in ThemeManager', () => {
ThemeManager.setTheme({
components: {
Image: {
sourceTransformer: jest.fn(() => 3)
}
}
});
const uut = new Image({source: 1});
expect(uut.getImageSource()).toBe(3);
});
// TODO: currently impossible to test it cause we can't export the Image we use in tests
// with asBaseComponent
// it('should return transformed source prop, according to sourceTransform in ThemeManager', () => {
// ThemeManager.setTheme({
// components: {
// Image: {
// sourceTransformer: jest.fn(() => 3)
// }
// }
// });
// const uut = new Image({source: 1});
// expect(uut.getImageSource()).toBe(3);
// });

it('should return transformed source prop, according to sourceTransform prop and other given props', () => {
const sourceTransformer = jest.fn(({size, source}) => (size === 'small' ? source : 3));
Expand Down
124 changes: 67 additions & 57 deletions src/components/image/index.js → src/components/image/index.tsx
Original file line number Diff line number Diff line change
@@ -1,75 +1,80 @@
import _ from 'lodash';
import PropTypes from 'prop-types';
import React from 'react';
import React, {PureComponent} from 'react';
//@ts-ignore
import hoistNonReactStatic from 'hoist-non-react-statics';
import {Image as RNImage, StyleSheet, ImageBackground} from 'react-native';
import {Constants} from '../../helpers';
import {PureBaseComponent} from '../../commons';
import {Image as RNImage, ImageProps as RNImageProps, StyleSheet, ImageBackground} from 'react-native';
import Constants from '../../helpers/Constants';
import {asBaseComponent, forwardRef, ForwardRefInjectedProps} from '../../commons/new';
// @ts-ignore
import Assets from '../../assets';
import Overlay from '../overlay';
import Overlay, {OverlayTypeType} from '../overlay';

type ImageProps = RNImageProps & {
/**
* custom source transform handler for manipulating the image source (great for size control)
*/
sourceTransformer?: Function;
/**
* if provided image source will be driven from asset name
*/
assetName?: string;
/**
* the asset group, default is "icons"
*/
assetGroup?: string;
/**
* the asset tint
*/
tintColor?: string;
/**
* whether the image should flip horizontally on RTL locals
*/
supportRTL?: boolean;
/**
* Show image as a cover, full width, image (according to aspect ratio, default: 16:8)
*/
cover?: boolean;
/**
* The aspect ratio for the image
*/
aspectRatio?: number;
/**
* The type of overly to place on top of the image. Note: the image MUST have proper size, see examples in:
* https://github.com/wix/react-native-ui-lib/blob/master/demo/src/screens/componentScreens/OverlaysScreen.js
*/
overlayType?: OverlayTypeType;
/**
* Pass a custom color for the overlay
*/
overlayColor?: string;
/**
* Render an overlay with custom content
*/
customOverlayContent?: JSX.Element;
};

type Props = ImageProps & ForwardRefInjectedProps;

/**
* @description: Image wrapper with extra functionality like source transform and assets support
* @extends: Image
* @extendslink: https://facebook.github.io/react-native/docs/image.html
*/
class Image extends PureBaseComponent {
class Image extends PureComponent<Props> {
static displayName = 'Image';

static propTypes = {
/**
* custom source transform handler for manipulating the image source (great for size control)
*/
sourceTransformer: PropTypes.func,
/**
* if provided image source will be driven from asset name
*/
assetName: PropTypes.string,
/**
* the asset group, default is "icons"
*/
assetGroup: PropTypes.string,
/**
* the asset tint
*/
tintColor: PropTypes.string,
/**
* whether the image should flip horizontally on RTL locals
*/
supportRTL: PropTypes.bool,
/**
* Show image as a cover, full width, image (according to aspect ratio, default: 16:8)
*/
cover: PropTypes.bool,
/**
* The aspect ratio for the image
*/
aspectRatio: PropTypes.number,
/**
* The type of overly to place on top of the image. Note: the image MUST have proper size, see examples in:
* https://github.com/wix/react-native-ui-lib/blob/master/demo/src/screens/componentScreens/OverlaysScreen.js
*/
overlayType: Overlay.propTypes.type,
/**
* Pass a custom color for the overlay
*/
overlayColor: PropTypes.string,
/**
* Render an overlay with custom content
*/
customOverlayContent: PropTypes.element
};

static defaultProps = {
assetGroup: 'icons'
};

static overlayTypes = Overlay.overlayTypes;
public static overlayTypes = Overlay.overlayTypes;

sourceTransformer?: Function;

constructor(props) {
constructor(props: Props) {
super(props);

this.sourceTransformer = this.getThemeProps().sourceTransformer;
this.sourceTransformer = this.props.sourceTransformer;
}

isGif() {
Expand Down Expand Up @@ -99,6 +104,7 @@ class Image extends PureBaseComponent {

const {source} = this.props;
if (_.get(source, 'uri') === null || _.get(source, 'uri') === '') {
// @ts-ignore
return {...source, uri: undefined};
}

Expand All @@ -116,13 +122,16 @@ class Image extends PureBaseComponent {
overlayType,
overlayColor,
customOverlayContent,
forwardedRef,
...others
} = this.getThemeProps();
} = this.props;
const shouldFlipRTL = supportRTL && Constants.isRTL;
const ImageView = this.shouldUseImageBackground() ? ImageBackground : RNImage;

return (
// @ts-ignore
<ImageView
ref={forwardedRef}
style={[
{tintColor},
shouldFlipRTL && styles.rtlFlipped,
Expand All @@ -137,7 +146,7 @@ class Image extends PureBaseComponent {
source={source}
>
{(overlayType || customOverlayContent) && (
<Overlay style={style} type={overlayType} color={overlayColor} customContent={customOverlayContent}/>
<Overlay type={overlayType} color={overlayColor} customContent={customOverlayContent}/>
)}
</ImageView>
);
Expand All @@ -158,4 +167,5 @@ const styles = StyleSheet.create({
});

hoistNonReactStatic(Image, RNImage);
export default Image;
export {Image};
export default asBaseComponent<ImageProps>(forwardRef(Image));
Loading