1
1
import type { ReactElement } from 'react' ;
2
2
import type { SvgProps } from 'react-native-svg' ;
3
3
4
- import { useCallback , useEffect , useState } from 'react' ;
4
+ import { useMemo } from 'react' ;
5
5
import { z } from 'zod' ;
6
6
7
7
import { useTheme } from '@/theme' ;
@@ -15,60 +15,46 @@ const icons = getAssetsContext('icons');
15
15
const EXTENSION = 'svg' ;
16
16
17
17
function IconByVariant ( { height = 24 , path, width = 24 , ...props } : Props ) {
18
- const [ icon , setIcon ] = useState < ReactElement < SvgProps > > ( ) ;
19
18
const { variant } = useTheme ( ) ;
20
19
21
- useEffect ( ( ) => {
20
+ const iconProps = { ...props , height, width } ;
21
+ const Icon = useMemo ( ( ) => {
22
22
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 ;
26
29
27
30
if ( variant === 'default' ) {
28
- setIcon ( defaultSource . default ) ;
29
- return ;
31
+ return getDefaultSource ( ) ;
30
32
}
31
33
32
34
try {
33
35
const fetchedModule = z
34
- . object ( { default : z . custom < ReactElement < SvgProps > > ( ) } )
36
+ . object ( {
37
+ default : z . function ( ) . returns ( z . custom < ReactElement < SvgProps > > ( ) ) ,
38
+ } )
35
39
. parse ( icons ( `./${ variant } /${ path } .${ EXTENSION } ` ) ) ;
36
40
37
- setIcon ( fetchedModule . default ) ;
41
+ return fetchedModule . default ;
38
42
} catch ( error ) {
39
43
// eslint-disable-next-line no-console
40
44
console . warn (
41
45
`Couldn't load the icon: ${ path } .${ EXTENSION } for the variant ${ variant } , Fallback to default` ,
42
46
error ,
43
47
) ;
44
- setIcon ( defaultSource . default ) ;
48
+ return getDefaultSource ( ) ;
45
49
}
46
50
} catch ( error ) {
47
51
// eslint-disable-next-line no-console
48
52
console . error ( `Couldn't load the icon: ${ path } .${ EXTENSION } ` , error ) ;
53
+ throw error ;
49
54
}
50
55
} , [ variant , path ] ) ;
51
56
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 } /> ;
72
58
}
73
59
74
60
export default IconByVariant ;
0 commit comments