-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathIcon.tsx
More file actions
105 lines (96 loc) · 2.54 KB
/
Copy pathIcon.tsx
File metadata and controls
105 lines (96 loc) · 2.54 KB
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
94
95
96
97
98
99
100
101
102
103
104
105
import { useRef } from 'react';
import styled from 'styled-components';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import {
IconName,
IconPrefix,
findIconDefinition,
} from '@fortawesome/fontawesome-svg-core';
import { includes } from 'ramda';
import cls from 'classnames';
import { createSpacings, getColor } from '../../utils';
import { IconTypes } from '../../theme/icons/icons.enums';
import { IconProps } from './Icon.types';
import { CLX_COMPONENT } from '../../theme/constants';
import { useLogger } from '../../hooks/useLogger';
const fontSizes: Record<IconProps['size'], string> = {
sm: '0.875rem',
md: '1rem',
lg: '1.5rem',
xl: '2rem',
};
const boxSizes: Record<IconProps['size'], string> = {
sm: '1rem',
md: '1.5rem',
lg: '2rem',
xl: '2.5rem',
};
const IconBox = styled.div<{
$size: IconProps['size'];
}>`
display: inline-grid;
place-items: center;
width: ${({ $size }) => boxSizes[$size]};
height: ${({ $size }) => boxSizes[$size]};
`;
const getIconColor = ({ $color, theme }): string | undefined => {
if (typeof $color === 'undefined') return 'inherit';
if ($color.startsWith('var(')) return $color;
return getColor($color, { theme });
};
const StyledIcon = styled(FontAwesomeIcon).withConfig<{
$color: IconProps['color'];
$size: IconProps['size'];
$hasFixedSize: IconProps['hasFixedSize'];
}>({
shouldForwardProp: (property) => !includes(property, ['margin']),
})`
color: ${getIconColor};
font-size: ${({ $size }) => $size && fontSizes[$size]};
${createSpacings};
transition: transform 200ms var(--sscds-transition-fn);
`;
const Icon = ({
name,
type = IconTypes.ssc,
color,
size,
className = '',
hasFixedWidth = false,
hasFixedSize,
...props
}: IconProps) => {
const { warn } = useLogger('Icon');
const ref = useRef<SVGSVGElement>(null);
const iconDefinition = findIconDefinition({
iconName: name as IconName,
prefix: type as IconPrefix,
});
if (iconDefinition === undefined) {
warn(
`Used icon was not found. You need to import it in the icon library. Looking for prefix: ${type}, name: ${name}`,
);
return null;
}
const icon = (
<StyledIcon
ref={ref}
$color={color}
$hasFixedSize={hasFixedSize}
$size={size}
className={cls(CLX_COMPONENT, className)}
fixedWidth={hasFixedWidth}
icon={iconDefinition}
{...props}
/>
);
if (hasFixedSize) {
return (
<IconBox $size={size} className="sscds-iconbox">
{icon}
</IconBox>
);
}
return icon;
};
export default Icon;