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