diff --git a/src/components/Icon/index.tsx b/src/components/Icon/index.tsx index 92ec50cbc612..e71d21077eda 100644 --- a/src/components/Icon/index.tsx +++ b/src/components/Icon/index.tsx @@ -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; @@ -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 { // eslint-disable-next-line react/static-property-placement - public static defaultProps = { + public static defaultProps: Partial = { width: variables.iconSizeNormal, height: variables.iconSizeNormal, fill: undefined, diff --git a/src/components/ImageSVG/imageSVGPropTypes.js b/src/components/ImageSVG/imageSVGPropTypes.js deleted file mode 100644 index f1069043f08e..000000000000 --- a/src/components/ImageSVG/imageSVGPropTypes.js +++ /dev/null @@ -1,47 +0,0 @@ -import PropTypes from 'prop-types'; -import sourcePropTypes from '@components/Image/sourcePropTypes'; - -const propTypes = { - /** The asset to render. */ - src: PropTypes.oneOfType([PropTypes.func, sourcePropTypes]).isRequired, - - /** The width of the image. */ - width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), - - /** The height of the image. */ - height: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), - - /** The fill color for the image. Can be hex, rgb, rgba, or valid react-native named color such as 'red' or 'blue'. */ - fill: PropTypes.string, - - /** Is image hovered */ - hovered: PropTypes.bool, - - /** Is image pressed */ - pressed: PropTypes.bool, - - /** Determines how the image should be resized to fit its container */ - contentFit: PropTypes.string, - - style: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.object), PropTypes.object]), - - /** The pointer-events attribute allows us to define whether or when an element may be the target of a mouse event. */ - pointerEvents: PropTypes.string, - - /** 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: PropTypes.string, -}; - -const defaultProps = { - fill: undefined, - width: '100%', - height: '100%', - hovered: false, - pressed: false, - contentFit: 'cover', - style: [], - pointerEvents: undefined, - preserveAspectRatio: undefined, -}; - -export {propTypes, defaultProps}; diff --git a/src/components/ImageSVG/index.native.js b/src/components/ImageSVG/index.native.tsx similarity index 62% rename from src/components/ImageSVG/index.native.js rename to src/components/ImageSVG/index.native.tsx index 5bf459e445b0..c397e047b7e0 100644 --- a/src/components/ImageSVG/index.native.js +++ b/src/components/ImageSVG/index.native.tsx @@ -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 ( ; + const additionalProps: Pick = {}; if (fill) { additionalProps.fill = fill; @@ -21,9 +22,9 @@ function ImageSVG({src, width, height, fill, hovered, pressed, style, pointerEve @@ -31,6 +32,4 @@ function ImageSVG({src, width, height, fill, hovered, pressed, style, pointerEve } ImageSVG.displayName = 'ImageSVG'; -ImageSVG.propTypes = propTypes; -ImageSVG.defaultProps = defaultProps; export default ImageSVG; diff --git a/src/components/ImageSVG/types.ts b/src/components/ImageSVG/types.ts new file mode 100644 index 000000000000..cc580651c30c --- /dev/null +++ b/src/components/ImageSVG/types.ts @@ -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; + + /** 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;