1
- import React , { useMemo , useState } from 'react'
2
- import PropTypes from 'prop-types'
1
+ import React , { HTMLAttributes , FC , useState , useMemo } from 'react'
3
2
import classNames from 'classnames'
4
3
import './CIcon.css'
5
4
5
+ export interface CIconProps extends HTMLAttributes < SVGSVGElement > {
6
+ /**
7
+ * A string of all className you want applied to the component. [docs]
8
+ */
9
+ className ?: string
10
+ /**
11
+ * Name of the icon placed in React object. [docs]
12
+ */
13
+ name ?: string
14
+ /**
15
+ * Icon SVG content. [docs]
16
+ */
17
+ content ?: string | Array < string >
18
+ /**
19
+ * Size of the icon. Available sizes: 'sm', 'lg', 'xl', '2xl'...'9xl', 'custom', 'custom-size'. [docs]
20
+ */
21
+ size ?: 'custom' | 'custom-size' | 'sm' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl' | '6xl' | '7xl' | '8xl' | '9xl'
22
+ /**
23
+ * Use for replacing default CIcon component classes. Prop is overriding the 'size' prop. [docs]
24
+ */
25
+ customClasses ?: string | object | Array < string >
26
+ /**
27
+ * Link to the icon. If defined component will be rendered as 'img' tag. [docs]
28
+ */
29
+ src ?: string
30
+ /**
31
+ * If defined component will be rendered using 'use' tag. [docs]
32
+ */
33
+ use ?: string
34
+ /**
35
+ * Title tag content. [docs]
36
+ */
37
+ title ?: string
38
+ }
39
+
6
40
let warned = { }
7
- const colog = ( msg , icon ) => {
8
- if ( ! warned [ icon ] && process && process . env && process . env . NODE_ENV === 'development' ) {
41
+ const colog = ( msg : string , icon ?: string ) => {
42
+ if ( icon && ! warned [ icon ] && process && process . env && process . env . NODE_ENV === 'development' ) {
9
43
warned [ icon ] = true
10
44
console . error ( msg )
11
45
}
12
46
}
13
47
14
- const toCamelCase = ( str ) => {
48
+ const toCamelCase = ( str : string ) => {
15
49
return str . replace ( / ( [ - _ ] [ a - z 0 - 9 ] ) / ig, ( $1 ) => {
16
50
return $1 . toUpperCase ( )
17
51
} ) . replace ( / - / ig, '' )
18
52
}
19
53
20
54
//component - CoreUI / CIcon
21
- const CIcon = props => {
22
-
23
- const {
24
- className,
25
- name,
26
- content,
27
- customClasses,
28
- size,
29
- src,
30
- title,
31
- use,
32
- ...attributes
33
- } = props
55
+ const CIcon : FC < CIconProps > = ( {
56
+ className,
57
+ name,
58
+ content,
59
+ customClasses,
60
+ size,
61
+ src,
62
+ title,
63
+ use,
64
+ ...rest
65
+ } ) => {
34
66
35
67
const [ change , setChange ] = useState ( 0 )
36
68
37
- useMemo ( ( ) => setChange ( change + 1 ) , [ name , JSON . stringify [ content ] ] )
69
+ useMemo ( ( ) => setChange ( change + 1 ) , [ name , JSON . stringify ( content ) ] )
38
70
39
- const iconName = useMemo ( ( ) => {
40
- const iconNameIsKebabCase = name && name . includes ( '-' )
41
- return iconNameIsKebabCase ? toCamelCase ( name ) : name
42
- } , [ change ] )
71
+ const iconName = useMemo ( ( ) => ( name && name . includes ( '-' ) ) ? toCamelCase ( name ) : name , [ change ] )
43
72
44
73
const titleCode = title ? `<title>${ title } </title>` : ''
45
74
46
75
const code = useMemo ( ( ) => {
47
76
if ( content ) {
48
77
return content
49
- } else if ( name && React . icons ) {
50
- return React . icons [ iconName ] ? React . icons [ iconName ] :
78
+ } else if ( name && React [ ' icons' ] ) {
79
+ return React [ ' icons' ] [ iconName ] ? React [ ' icons' ] [ iconName ] :
51
80
colog ( `CIcon component: icon name '${ iconName } ' does not exist in React.icons object. ` +
52
- `To use icons by 'name' prop you need to make them available globally ` +
81
+ `To use icons by 'name' prop you need to make them available globally ` +
53
82
`by adding them to React.icons object. CIcon component docs: https://coreui.io/react/docs/components/CIcon \n` ,
54
83
iconName
55
84
)
@@ -65,28 +94,38 @@ const CIcon = props => {
65
94
} ) ( )
66
95
67
96
const viewBox = ( ( ) => {
68
- return attributes . viewBox || `0 0 ${ scale } `
97
+ return rest [ ' viewBox' ] || `0 0 ${ scale } `
69
98
} ) ( )
70
99
71
- const computedSize = ( ( ) => {
72
- const addCustom = ! size && ( attributes . width || attributes . height )
73
- return size === 'custom' || addCustom ? 'custom-size' : size
74
- } ) ( )
100
+ // render
75
101
76
- //render
77
- const computedClasses = classNames (
78
- 'c-icon' ,
79
- computedSize && `c-icon-${ computedSize } ` ,
80
- className
81
- )
102
+ let classes
82
103
83
- const classes = customClasses || computedClasses
104
+ if ( customClasses ) {
105
+ classes = classNames (
106
+ customClasses
107
+ )
108
+ }
109
+ else
110
+ {
111
+ const computedSize = ( ( ) => {
112
+ const addCustom = ! size && ( rest [ 'width' ] || rest [ 'height' ] )
113
+ return size === 'custom' || addCustom ? 'custom-size' : size
114
+ } ) ( )
115
+ classes = classNames (
116
+ 'c-icon' ,
117
+ computedSize && `c-icon-${ computedSize } ` ,
118
+ className
119
+ )
120
+ }
121
+
122
+ //const classes = customClasses || computedClasses
84
123
85
124
return (
86
125
< React . Fragment >
87
126
{ ! src && ! use &&
88
127
< svg
89
- { ...attributes }
128
+ { ...rest }
90
129
xmlns = "http://www.w3.org/2000/svg"
91
130
viewBox = { viewBox }
92
131
className = { classes }
@@ -96,15 +135,14 @@ const CIcon = props => {
96
135
}
97
136
{ src && ! use &&
98
137
< img
99
- { ...attributes }
100
138
className = { className }
101
139
src = { src }
102
140
role = "img"
103
141
/>
104
142
}
105
143
{ ! src && use &&
106
144
< svg
107
- { ...attributes }
145
+ { ...rest }
108
146
xmlns = "http://www.w3.org/2000/svg"
109
147
className = { classes }
110
148
role = "img"
@@ -114,25 +152,14 @@ const CIcon = props => {
114
152
}
115
153
</ React . Fragment >
116
154
)
117
- }
118
155
119
- CIcon . propTypes = {
120
- className : PropTypes . string ,
121
- name : PropTypes . string ,
122
- content : PropTypes . oneOfType ( [ PropTypes . string , PropTypes . array ] ) ,
123
- size : PropTypes . oneOf ( [
124
- 'custom' , 'custom-size' , 'sm' , 'lg' , 'xl' ,
125
- '2xl' , '3xl' , '4xl' , '5xl' , '6xl' , '7xl' , '8xl' , '9xl'
126
- ] ) ,
127
- customClasses : PropTypes . oneOfType ( [ PropTypes . string , PropTypes . array , PropTypes . object ] ) ,
128
- src : PropTypes . string ,
129
- title : PropTypes . string ,
130
- use : PropTypes . string
131
156
}
132
157
133
158
export default CIcon
134
159
135
- export const CIconWarn = props => {
160
+ //
161
+
162
+ export const CIconWarn : FC < CIconProps > = ( props ) => {
136
163
colog (
137
164
'@coreui/icons-react: Please use default export since named exports are deprecated'
138
165
)
0 commit comments