2024-01-03 04:49:48 +03:00
|
|
|
import moize from 'moize';
|
2023-12-23 13:05:30 +03:00
|
|
|
import { useEffect, useRef, useState } from 'preact/hooks';
|
2022-12-13 15:42:09 +03:00
|
|
|
|
2024-01-20 05:25:47 +03:00
|
|
|
import { ICONS } from './ICONS';
|
|
|
|
|
2022-12-10 12:14:48 +03:00
|
|
|
const SIZES = {
|
|
|
|
s: 12,
|
|
|
|
m: 16,
|
|
|
|
l: 20,
|
|
|
|
xl: 24,
|
|
|
|
xxl: 32,
|
|
|
|
};
|
|
|
|
|
2023-12-23 07:14:11 +03:00
|
|
|
const ICONDATA = {};
|
|
|
|
|
2024-01-03 04:49:48 +03:00
|
|
|
// Memoize the dangerouslySetInnerHTML of the SVGs
|
|
|
|
const SVGICon = moize(
|
|
|
|
function ({ size, width, height, body, rotate, flip }) {
|
|
|
|
return (
|
|
|
|
<svg
|
2024-01-19 20:45:54 +03:00
|
|
|
// width={size}
|
|
|
|
// height={size}
|
2024-01-03 04:49:48 +03:00
|
|
|
viewBox={`0 0 ${width} ${height}`}
|
|
|
|
dangerouslySetInnerHTML={{ __html: body }}
|
|
|
|
style={{
|
|
|
|
transform: `${rotate ? `rotate(${rotate})` : ''} ${
|
|
|
|
flip ? `scaleX(-1)` : ''
|
|
|
|
}`,
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
},
|
|
|
|
{
|
|
|
|
isShallowEqual: true,
|
|
|
|
maxSize: Object.keys(ICONS).length,
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
2023-03-09 16:51:50 +03:00
|
|
|
function Icon({
|
|
|
|
icon,
|
|
|
|
size = 'm',
|
|
|
|
alt,
|
|
|
|
title,
|
|
|
|
class: className = '',
|
|
|
|
style = {},
|
|
|
|
}) {
|
2022-12-14 16:48:17 +03:00
|
|
|
if (!icon) return null;
|
|
|
|
|
2022-12-10 12:14:48 +03:00
|
|
|
const iconSize = SIZES[size];
|
2023-07-12 11:42:58 +03:00
|
|
|
let iconBlock = ICONS[icon];
|
2024-01-04 13:55:21 +03:00
|
|
|
if (!iconBlock) {
|
|
|
|
console.warn(`Icon ${icon} not found`);
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2022-12-22 05:35:39 +03:00
|
|
|
let rotate, flip;
|
2023-07-12 11:42:58 +03:00
|
|
|
if (Array.isArray(iconBlock)) {
|
|
|
|
[iconBlock, rotate, flip] = iconBlock;
|
2022-12-13 15:42:09 +03:00
|
|
|
}
|
2023-01-11 04:47:46 +03:00
|
|
|
|
2023-12-23 07:14:11 +03:00
|
|
|
const [iconData, setIconData] = useState(ICONDATA[icon]);
|
2023-12-23 13:05:30 +03:00
|
|
|
const currentIcon = useRef(icon);
|
2023-12-23 07:14:11 +03:00
|
|
|
useEffect(() => {
|
2023-12-23 13:05:30 +03:00
|
|
|
if (iconData && currentIcon.current === icon) return;
|
2023-12-23 07:14:11 +03:00
|
|
|
(async () => {
|
|
|
|
const iconB = await iconBlock();
|
|
|
|
setIconData(iconB.default);
|
|
|
|
ICONDATA[icon] = iconB.default;
|
|
|
|
})();
|
2023-12-23 13:05:30 +03:00
|
|
|
currentIcon.current = icon;
|
|
|
|
}, [icon]);
|
2023-01-11 04:47:46 +03:00
|
|
|
|
2022-12-10 12:14:48 +03:00
|
|
|
return (
|
2023-09-29 16:02:09 +03:00
|
|
|
<span
|
2022-12-10 12:14:48 +03:00
|
|
|
class={`icon ${className}`}
|
|
|
|
title={title || alt}
|
|
|
|
style={{
|
|
|
|
width: `${iconSize}px`,
|
|
|
|
height: `${iconSize}px`,
|
2023-03-09 16:51:50 +03:00
|
|
|
...style,
|
2022-12-10 12:14:48 +03:00
|
|
|
}}
|
|
|
|
>
|
2023-01-11 04:47:46 +03:00
|
|
|
{iconData && (
|
2024-01-03 04:49:48 +03:00
|
|
|
// <svg
|
|
|
|
// width={iconSize}
|
|
|
|
// height={iconSize}
|
|
|
|
// viewBox={`0 0 ${iconData.width} ${iconData.height}`}
|
|
|
|
// dangerouslySetInnerHTML={{ __html: iconData.body }}
|
|
|
|
// style={{
|
|
|
|
// transform: `${rotate ? `rotate(${rotate})` : ''} ${
|
|
|
|
// flip ? `scaleX(-1)` : ''
|
|
|
|
// }`,
|
|
|
|
// }}
|
|
|
|
// />
|
|
|
|
<SVGICon
|
|
|
|
size={iconSize}
|
|
|
|
width={iconData.width}
|
|
|
|
height={iconData.height}
|
|
|
|
body={iconData.body}
|
|
|
|
rotate={rotate}
|
|
|
|
flip={flip}
|
2023-01-11 04:47:46 +03:00
|
|
|
/>
|
|
|
|
)}
|
2023-09-29 16:02:09 +03:00
|
|
|
</span>
|
2022-12-10 12:14:48 +03:00
|
|
|
);
|
2022-12-16 08:27:04 +03:00
|
|
|
}
|
|
|
|
|
2023-12-24 16:05:43 +03:00
|
|
|
export default Icon;
|