11import type { ReactElement } from 'react' ;
22import type { SvgProps } from 'react-native-svg' ;
33
4- import { useCallback , useEffect , useState } from 'react' ;
4+ import { useMemo } from 'react' ;
55import { z } from 'zod' ;
66
77import { useTheme } from '@/theme' ;
@@ -15,60 +15,46 @@ const icons = getAssetsContext('icons');
1515const EXTENSION = 'svg' ;
1616
1717function IconByVariant ( { height = 24 , path, width = 24 , ...props } : Props ) {
18- const [ icon , setIcon ] = useState < ReactElement < SvgProps > > ( ) ;
1918 const { variant } = useTheme ( ) ;
2019
21- useEffect ( ( ) => {
20+ const iconProps = { ...props , height, width } ;
21+ const Icon = useMemo ( ( ) => {
2222 try {
23- const defaultSource = z
24- . object ( { default : z . custom < ReactElement < SvgProps > > ( ) } )
25- . parse ( icons ( `./${ path } .${ EXTENSION } ` ) ) ;
23+ const getDefaultSource = ( ) =>
24+ z
25+ . object ( {
26+ default : z . function ( ) . returns ( z . custom < ReactElement < SvgProps > > ( ) ) ,
27+ } )
28+ . parse ( icons ( `./${ path } .${ EXTENSION } ` ) ) . default ;
2629
2730 if ( variant === 'default' ) {
28- setIcon ( defaultSource . default ) ;
29- return ;
31+ return getDefaultSource ( ) ;
3032 }
3133
3234 try {
3335 const fetchedModule = z
34- . object ( { default : z . custom < ReactElement < SvgProps > > ( ) } )
36+ . object ( {
37+ default : z . function ( ) . returns ( z . custom < ReactElement < SvgProps > > ( ) ) ,
38+ } )
3539 . parse ( icons ( `./${ variant } /${ path } .${ EXTENSION } ` ) ) ;
3640
37- setIcon ( fetchedModule . default ) ;
41+ return fetchedModule . default ;
3842 } catch ( error ) {
3943 // eslint-disable-next-line no-console
4044 console . warn (
4145 `Couldn't load the icon: ${ path } .${ EXTENSION } for the variant ${ variant } , Fallback to default` ,
4246 error ,
4347 ) ;
44- setIcon ( defaultSource . default ) ;
48+ return getDefaultSource ( ) ;
4549 }
4650 } catch ( error ) {
4751 // eslint-disable-next-line no-console
4852 console . error ( `Couldn't load the icon: ${ path } .${ EXTENSION } ` , error ) ;
53+ throw error ;
4954 }
5055 } , [ variant , path ] ) ;
5156
52- const Component = useCallback (
53- ( currentProps : SvgProps ) => {
54- if ( ! icon ) {
55- return null ;
56- }
57-
58- return {
59- ...icon ,
60- props : {
61- ...icon . props ,
62- height,
63- width,
64- ...currentProps ,
65- } ,
66- } ;
67- } ,
68- [ icon , width , height ] ,
69- ) ;
70-
71- return < Component { ...props } /> ;
57+ return < Icon { ...iconProps } /> ;
7258}
7359
7460export default IconByVariant ;
0 commit comments