Skip to content

Commit

Permalink
Migrate ImageSVG to TS
Browse files Browse the repository at this point in the history
  • Loading branch information
WojtekBoman committed Dec 11, 2023
1 parent 9647214 commit 95e49d0
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 76 deletions.
25 changes: 9 additions & 16 deletions src/components/Icon/index.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
import {ImageContentFit} from 'expo-image';
import React, {PureComponent} from 'react';
import {ImageSourcePropType, StyleProp, View, ViewStyle} from 'react-native';
import {StyleProp, View, ViewStyle} from 'react-native';
import ImageSVG from '@components/ImageSVG';
import withStyleUtils, {WithStyleUtilsProps} from '@components/withStyleUtils';
import withTheme, {WithThemeProps} from '@components/withTheme';
import withThemeStyles, {type WithThemeStylesProps} from '@components/withThemeStyles';
import variables from '@styles/variables';
import IconAsset from '@src/types/utils/IconAsset';
import IconWrapperStyles from './IconWrapperStyles';

type SrcProps = {
width?: number;
height?: number;
fill?: string;
hovered?: string;
pressed?: string;
};

type IconProps = {
type IconBaseProps = {
/** The asset to render. */
src: ((props: SrcProps) => React.ReactNode) | ImageSourcePropType;
src: IconAsset;

/** The width of the icon. */
width?: number;
Expand Down Expand Up @@ -47,16 +41,15 @@ type IconProps = {
testID?: string;

/** Determines how the image should be resized to fit its container */
contentFit?: string;
} & WithThemeStylesProps &
WithThemeProps &
WithStyleUtilsProps;
contentFit?: ImageContentFit;
};
type IconProps = IconBaseProps & WithThemeStylesProps & WithThemeProps & WithStyleUtilsProps;

// We must use a class component to create an animatable component with the Animated API
// eslint-disable-next-line react/prefer-stateless-function
class Icon extends PureComponent<IconProps> {
// eslint-disable-next-line react/static-property-placement
public static defaultProps = {
public static defaultProps: Partial<IconBaseProps> = {
width: variables.iconSizeNormal,
height: variables.iconSizeNormal,
fill: undefined,
Expand Down
47 changes: 0 additions & 47 deletions src/components/ImageSVG/imageSVGPropTypes.js

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import {Image} from 'expo-image';
import React from 'react';
import {defaultProps, propTypes} from './imageSVGPropTypes';
import {ImageSourcePropType} from 'react-native';
import ImageSVGProps from './types';

function ImageSVG({src, width, height, fill, contentFit, style}) {
function ImageSVG({src, width = '100%', height = '100%', fill, contentFit = 'cover', style}: ImageSVGProps) {
const tintColorProp = fill ? {tintColor: fill} : {};

return (
<Image
contentFit={contentFit}
source={src}
source={src as ImageSourcePropType}
style={[{width, height}, style]}
// eslint-disable-next-line react/jsx-props-no-spreading
{...tintColorProp}
Expand All @@ -17,6 +18,4 @@ function ImageSVG({src, width, height, fill, contentFit, style}) {
}

ImageSVG.displayName = 'ImageSVG';
ImageSVG.propTypes = propTypes;
ImageSVG.defaultProps = defaultProps;
export default ImageSVG;
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React from 'react';
import {defaultProps, propTypes} from './imageSVGPropTypes';
import {SvgProps} from 'react-native-svg';
import ImageSVGProps from './types';

function ImageSVG({src, width, height, fill, hovered, pressed, style, pointerEvents, preserveAspectRatio}) {
const ImageSvgComponent = src;
const additionalProps = {};
function ImageSVG({src, width = '100%', height = '100%', fill, hovered = false, pressed = false, style, pointerEvents, preserveAspectRatio}: ImageSVGProps) {
const ImageSvgComponent = src as React.FC<SvgProps>;
const additionalProps: Pick<ImageSVGProps, 'fill' | 'pointerEvents' | 'preserveAspectRatio'> = {};

if (fill) {
additionalProps.fill = fill;
Expand All @@ -21,16 +22,14 @@ function ImageSVG({src, width, height, fill, hovered, pressed, style, pointerEve
<ImageSvgComponent
width={width}
height={height}
hovered={hovered.toString()}
pressed={pressed.toString()}
style={style}
hovered={`${hovered}`}
pressed={`${pressed}`}
// eslint-disable-next-line react/jsx-props-no-spreading
{...additionalProps}
/>
);
}

ImageSVG.displayName = 'ImageSVG';
ImageSVG.propTypes = propTypes;
ImageSVG.defaultProps = defaultProps;
export default ImageSVG;
37 changes: 37 additions & 0 deletions src/components/ImageSVG/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import {ImageContentFit, ImageStyle} from 'expo-image';
import {StyleProp, ViewStyle} from 'react-native';
import IconAsset from '@src/types/utils/IconAsset';

type ImageSVGProps = {
/** The asset to render. */
src: IconAsset;

/** The width of the image. */
width?: number | `${number}%` | 'auto';

/** The height of the image. */
height?: number | `${number}%` | 'auto';

/** The fill color for the image. Can be hex, rgb, rgba, or valid react-native named color such as 'red' or 'blue'. */
fill?: string;

/** Is image hovered */
hovered?: boolean;

/** Is image pressed */
pressed?: boolean;

/** Additional styles to add to the component */
style?: StyleProp<ViewStyle & ImageStyle>;

/** Determines how the image should be resized to fit its container */
contentFit?: ImageContentFit;

/** The pointer-events attribute allows us to define whether or when an element may be the target of a mouse event. */
pointerEvents?: 'box-none' | 'none' | 'box-only' | 'auto';

/** The preserveAspectRatio attribute indicates how an element with a viewBox providing a given aspect ratio must fit into a viewport with a different aspect ratio. */
preserveAspectRatio?: string;
};

export default ImageSVGProps;

0 comments on commit 95e49d0

Please sign in to comment.