8000 feat: add the `CIconSvg` component to allow adding custom SVG icons · coreui/coreui-icons-react@887491d · GitHub
[go: up one dir, main page]

Skip to content

Commit 887491d

Browse files
committed
feat: add the CIconSvg component to allow adding custom SVG icons
1 parent 6815481 commit 887491d

File tree

2 files changed

+106
-0
lines changed

2 files changed

+106
-0
lines changed

src/CIconSvg.tsx

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import React, { Children, HTMLAttributes, forwardRef } from 'react'
2+
import PropTypes from 'prop-types'
3+
import classNames from 'classnames'
4+
import './CIcon.css'
5+
6+
export interface CIconSvgProps extends Omit<HTMLAttributes<SVGSVGElement>, 'content'> {
7+
/**
8+
* A string of all className you want applied to the component.
9+
*/
10+
className?: string
11+
/**
12+
* Use for replacing default CIcon component classes. Prop is overriding the 'size' prop.
13+
*/
14+
customClassName?: string | string[]
15+
/**
16+
* The height attribute defines the vertical length of an icon.
17+
*/
18+
height?: number
19+
/**
20+
* Size of the icon. Available sizes: 'sm', 'lg', 'xl', 'xxl', '3xl...9xl', 'custom', 'custom-size'.
21+
*/
22+
size?:
23+
| 'custom'
24+
| 'custom-size'
25+
| 'sm'
26+
| 'lg'
27+
| 'xl'
28+
| 'xxl'
29+
| '3xl'
30+
| '4xl'
31+
| '5xl'
32+
| '6xl'
33+
| '7xl'
34+
| '8xl'
35+
| '9xl'
36+
/**
37+
* Title tag content.
38+
*/
39+
title?: string
40+
/**
41+
* The width attribute defines the horizontal length of an icon.
42+
*/
43+
width?: number
44+
}
45+
46+
export const CIconSvg = forwardRef<SVGSVGElement, CIconSvgProps>(
47+
({ children, className, customClassName, height, size, title, width, ...rest }, ref) => {
48+
const _className = customClassName
49+
? classNames(customClassName)
50+
: classNames(
51+
'icon',
52+
{
53+
[`icon-${size}`]: size,
54+
[`icon-custom-size`]: height || width,
55+
},
56+
className,
57+
)
58+
59+
return (
60+
<>
61+
{Children.map(children, (child) => {
62+
if (React.isValidElement(child)) {
63+
return React.cloneElement(child as React.ReactElement<any>, {
64+
'aria-hidden': true,
65+
className: _className,
66+
focusable: 'false',
67+
ref: ref,
68+
role: 'img',
69+
...rest,
70+
})
71+
}
72+
73+
return
74+
})}
75+
{title && <span className="visually-hidden">{title}</span>}
76+
</>
77+
)
78+
},
79+
)
80+
81+
CIconSvg.propTypes = {
82+
className: PropTypes.string,
83+
customClassName: PropTypes.string,
84+
height: PropTypes.number,
85+
size: PropTypes.oneOf([
86+
'custom',
87+
'custom-size',
88+
'sm',
89+
'lg',
90+
'xl',
91+
'xxl',
92+
'3xl',
93+
'4xl',
94+
'5xl',
95+
'6xl',
96+
'7xl',
97+
'8xl',
98+
'9xl',
99+
]),
100+
title: PropTypes.string,
101+
width: PropTypes.number,
102+
}
103+
104+
CIconSvg.displayName = 'CIconSvg'

src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
import { CIcon } from './CIcon'
2+
import { CIconSvg } from './CIconSvg'
23

4+
export { CIcon, CIconSvg }
35
export default CIcon

0 commit comments

Comments
 (0)
0