| 
 | 1 | +import React, { useMemo, useState } from 'react'  | 
 | 2 | +import PropTypes from 'prop-types'  | 
 | 3 | +import classNames from 'classnames'  | 
1 | 4 | import './CIcon.css'  | 
2 |  | -import CIcon from './CIconRaw'  | 
 | 5 | + | 
 | 6 | +const colog = (...args) => {  | 
 | 7 | +  if (process && process.env && process.env.NODE_ENV === 'development') {  | 
 | 8 | +    console.warn(...args)  | 
 | 9 | +  }  | 
 | 10 | +}  | 
 | 11 | + | 
 | 12 | +const toCamelCase = (str) => {  | 
 | 13 | +  return str.replace(/([-_][a-z0-9])/ig, ($1) => {  | 
 | 14 | +    return $1.toUpperCase()  | 
 | 15 | +  }).replaceAll('-', '')  | 
 | 16 | +}  | 
 | 17 | + | 
 | 18 | +//component - CoreUI / CIcon  | 
 | 19 | +const CIcon = props => {  | 
 | 20 | + | 
 | 21 | +  const {  | 
 | 22 | +    className,  | 
 | 23 | +    //  | 
 | 24 | +    name,  | 
 | 25 | +    content,  | 
 | 26 | +    customClasses,  | 
 | 27 | +    size,  | 
 | 28 | +    src,  | 
 | 29 | +    title,  | 
 | 30 | +    use,  | 
 | 31 | +    ...attributes  | 
 | 32 | +  } = props  | 
 | 33 | + | 
 | 34 | +  const [change, setChange] = useState(0)  | 
 | 35 | + | 
 | 36 | +  useMemo(() => setChange(change + 1), [name, JSON.stringify[content]])  | 
 | 37 | + | 
 | 38 | +  const iconName = useMemo(()=>{  | 
 | 39 | +    const iconNameIsKebabCase = name && name.includes('-')  | 
 | 40 | +    return iconNameIsKebabCase ? toCamelCase(name) : name  | 
 | 41 | +  }, [change])  | 
 | 42 | + | 
 | 43 | +  const titleCode = title ? `<title>${title}</title>` : ''  | 
 | 44 | + | 
 | 45 | +  const code = useMemo(() => {  | 
 | 46 | +    if (content) {  | 
 | 47 | +      return content  | 
 | 48 | +    } else if (name && React.icons) {  | 
 | 49 | +      return React.icons[iconName] ? React.icons[iconName] :  | 
 | 50 | +        colog('Not existing icon: '+ iconName + ' in React.icons object')  | 
 | 51 | +    }  | 
 | 52 | +  }, [change])  | 
 | 53 | + | 
 | 54 | +  const iconCode = useMemo(()=>{  | 
 | 55 | +    return Array.isArray(code) ? code[1] || code[0] : code  | 
 | 56 | +  }, [change])  | 
 | 57 | + | 
 | 58 | +  const scale = (()=>{  | 
 | 59 | +    return Array.isArray(code) && code.length > 1 ? code[0] : '64 64'  | 
 | 60 | +  })()  | 
 | 61 | + | 
 | 62 | +  const viewBox = (()=>{  | 
 | 63 | +    return attributes.viewBox || `0 0 ${scale}`  | 
 | 64 | +  })()  | 
 | 65 | + | 
 | 66 | +  const computedSize = (()=>{  | 
 | 67 | +    const addCustom = !size && (attributes.width || attributes.height)  | 
 | 68 | +    return size === 'custom' || addCustom ? 'custom-size' : size  | 
 | 69 | +  })()  | 
 | 70 | + | 
 | 71 | +  //render  | 
 | 72 | +  const computedClasses = classNames(  | 
 | 73 | +    'c-icon',  | 
 | 74 | +    computedSize && `c-icon-${computedSize}`,  | 
 | 75 | +    className  | 
 | 76 | +  )  | 
 | 77 | + | 
 | 78 | +  const classes = customClasses || computedClasses  | 
 | 79 | + | 
 | 80 | +  return (  | 
 | 81 | +    <React.Fragment>  | 
 | 82 | +      { !src && !use &&  | 
 | 83 | +        <svg  | 
 | 84 | +          {...attributes}  | 
 | 85 | +          xmlns="http://www.w3.org/2000/svg"  | 
 | 86 | +          viewBox={viewBox}  | 
 | 87 | +          className={classes}  | 
 | 88 | +          role="img"  | 
 | 89 | +          dangerouslySetInnerHTML={{__html: titleCode + iconCode}}  | 
 | 90 | +        />  | 
 | 91 | +      }  | 
 | 92 | +      { src && !use &&  | 
 | 93 | +        <img  | 
 | 94 | +          {...attributes}  | 
 | 95 | +          className={className}  | 
 | 96 | +          src={src}  | 
 | 97 | +          role="img"  | 
 | 98 | +        />  | 
 | 99 | +      }  | 
 | 100 | +      { !src && use &&  | 
 | 101 | +        <svg  | 
 | 102 | +          {...attributes}  | 
 | 103 | +          xmlns="http://www.w3.org/2000/svg"  | 
 | 104 | +          className={classes}  | 
 | 105 | +          role="img"  | 
 | 106 | +        >  | 
 | 107 | +          <use href={use}></use>  | 
 | 108 | +        </svg>  | 
 | 109 | +      }  | 
 | 110 | +    </React.Fragment>  | 
 | 111 | +  )  | 
 | 112 | +}  | 
 | 113 | + | 
 | 114 | +CIcon.propTypes = {  | 
 | 115 | +  className: PropTypes.string,  | 
 | 116 | +  //  | 
 | 117 | +  name: PropTypes.string,  | 
 | 118 | +  content: PropTypes.oneOfType([PropTypes.string, PropTypes.array]),  | 
 | 119 | +  size: PropTypes.oneOf([  | 
 | 120 | +    'custom', 'custom-size', 'sm', 'lg', 'xl',  | 
 | 121 | +    '2xl', '3xl', '4xl', '5xl', '6xl', '7xl', '8xl', '9xl'  | 
 | 122 | +  ]),  | 
 | 123 | +  customClasses: PropTypes.oneOfType([PropTypes.string, PropTypes.array, PropTypes.object]),  | 
 | 124 | +  src: PropTypes.string,  | 
 | 125 | +  title: PropTypes.string,  | 
 | 126 | +  use: PropTypes.string  | 
 | 127 | +}  | 
 | 128 | + | 
3 | 129 | export default CIcon  | 
 | 130 | + | 
 | 131 | +export const CIconWarn = props => {  | 
 | 132 | +  colog(  | 
 | 133 | +    '@coreui/icons-react: Please use default export since named exports are deprecated'  | 
 | 134 | +  )  | 
 | 135 | +  return <CIcon {...props}/>  | 
 | 136 | +}  | 
0 commit comments