forked from grafana/grafana
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathIcon.tsx
93 lines (79 loc) · 2.55 KB
/
Icon.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import { css, cx } from '@emotion/css';
import React from 'react';
import SVG from 'react-inlinesvg';
import { GrafanaTheme2, isIconName } from '@grafana/data';
import { useStyles2 } from '../../themes/ThemeContext';
import { IconName, IconType, IconSize } from '../../types/icon';
import { cacheInitialized, initIconCache, iconRoot } from './iconBundle';
import { getIconSubDir, getSvgSize } from './utils';
export interface IconProps extends React.HTMLAttributes<HTMLDivElement> {
name: IconName;
size?: IconSize;
type?: IconType;
title?: string;
}
const getIconStyles = (theme: GrafanaTheme2) => {
return {
// line-height: 0; is needed for correct icon alignment in Safari
container: css({
label: 'Icon',
display: 'inline-block',
lineHeight: 0,
}),
icon: css({
verticalAlign: 'middle',
display: 'inline-block',
fill: 'currentColor',
}),
orange: css({
fill: theme.v1.palette.orange,
}),
};
};
export const Icon = React.forwardRef<HTMLDivElement, IconProps>(
({ size = 'md', type = 'default', name, className, style, title = '', ...divElementProps }, ref): JSX.Element => {
const styles = useStyles2(getIconStyles);
/* Temporary solution to display also font awesome icons */
if (name?.startsWith('fa fa-')) {
/* @ts-ignore */
return <i className={getFontAwesomeIconStyles(name, className)} {...divElementProps} style={style} />;
}
if (!cacheInitialized) {
initIconCache();
}
if (!isIconName(name)) {
console.warn('Icon component passed an invalid icon name', name);
}
if (!name || name.includes('..')) {
return <div ref={ref}>invalid icon name</div>;
}
const svgSize = getSvgSize(size);
const svgHgt = svgSize;
const svgWid = name.startsWith('gf-bar-align') ? 16 : name.startsWith('gf-interp') ? 30 : svgSize;
const subDir = getIconSubDir(name, type);
const svgPath = `${iconRoot}${subDir}/${name}.svg`;
return (
<div className={styles.container} {...divElementProps} ref={ref}>
{/* @ts-ignore */}
<SVG
src={svgPath}
width={svgWid}
height={svgHgt}
title={title}
className={cx(styles.icon, className, type === 'mono' ? { [styles.orange]: name === 'favorite' } : '')}
style={style}
/>
</div>
);
}
);
Icon.displayName = 'Icon';
function getFontAwesomeIconStyles(iconName: string, className?: string): string {
return cx(
iconName,
{
'fa-spin': iconName === 'fa fa-spinner',
},
className
);
}