From dd63966289c2a7641dc8eff633d2233bd1b787fa Mon Sep 17 00:00:00 2001
From: "i.mirdzhamolov"
Date: Wed, 10 Aug 2022 14:46:43 +0300
Subject: [PATCH] feat: move icons to use `fontSize`
---
packages/icons-scripts/scripts/reactify.js | 21 ++++--
packages/icons-scripts/src/SvgIcon.tsx | 76 +++++++++++++++++-----
src/docs/docs.js | 39 +++++++++--
3 files changed, 110 insertions(+), 26 deletions(-)
diff --git a/packages/icons-scripts/scripts/reactify.js b/packages/icons-scripts/scripts/reactify.js
index 66693bfa1..8def69f32 100644
--- a/packages/icons-scripts/scripts/reactify.js
+++ b/packages/icons-scripts/scripts/reactify.js
@@ -2,9 +2,17 @@ const Compiler = require('svg-baker');
const compiler = new Compiler();
+function pxToEm(pxSize, baseSize) {
+ return `${Number((pxSize / baseSize).toFixed(4))}em`;
+}
+
const reactify = (symbol, componentName) => {
- const width = symbol.viewBox.split(' ')[2];
- const height = symbol.viewBox.split(' ')[3];
+ const defaultWidth = Number(symbol.viewBox.split(' ')[2]);
+ const defaultHeight = Number(symbol.viewBox.split(' ')[3]);
+
+ const baseSize = Math.max(defaultWidth, defaultHeight);
+ const relativeWidth = pxToEm(defaultWidth, baseSize);
+ const relativeHeight = pxToEm(defaultHeight, baseSize);
return `import { HTMLAttributes, RefCallback, RefObject } from 'react';
import { makeIcon } from '../SvgIcon';
@@ -20,9 +28,12 @@ export default makeIcon<${componentName}Props>(
'${componentName}',
'${symbol.id}',
'${symbol.viewBox}',
- '${symbol.render()}',
- ${width},
- ${height}
+ ${defaultWidth},
+ ${defaultHeight},
+ '${relativeWidth}',
+ '${relativeHeight}',
+ ${baseSize},
+ '${symbol.render()}'
);
`;
};
diff --git a/packages/icons-scripts/src/SvgIcon.tsx b/packages/icons-scripts/src/SvgIcon.tsx
index 3882210ea..645105c62 100644
--- a/packages/icons-scripts/src/SvgIcon.tsx
+++ b/packages/icons-scripts/src/SvgIcon.tsx
@@ -5,14 +5,29 @@ import { IconSettingsInterface, IconSettingsContext } from './IconSettings';
import { addSpriteSymbol, useIsomorphicLayoutEffect } from './sprite';
export interface SvgIconProps extends React.HTMLAttributes {
+ /**
+ * Для пропорционального изменения размера иконки относительно размера шрифта.
+ *
+ * > 📝 Чтобы размер наследовался от базового размера шрифта, передайте `"inherit"` или `"1em"`.
+ *
+ * @default берётся `Math.max(width, height)` иконки (см. `viewBox`)
+ */
+ fontSize?: string | number;
+ fill?: string;
width?: number;
height?: number;
viewBox?: string;
- fill?: string;
getRootRef?: React.RefCallback | React.RefObject;
Component?: React.ElementType,
}
+interface SvgIconInternalProps extends SvgIconProps {
+ defaultWidth: number;
+ defaultHeight: number;
+ relativeWidth: string;
+ relativeHeight: string;
+}
+
const svgStyle = { display: 'block' };
function iconClass(fragments: string[], { classPrefix, globalClasses }: IconSettingsInterface) {
@@ -28,9 +43,20 @@ function iconClass(fragments: string[], { classPrefix, globalClasses }: IconSett
return res;
}
-const SvgIcon: React.FC = ({
- width,
- height,
+const SvgIcon: React.FC = ({
+ /**
+ * Внутренние параметры (скрыты от пользователя)
+ */
+ defaultWidth,
+ defaultHeight,
+ relativeWidth,
+ relativeHeight,
+
+ /**
+ * Пользовательские параметры.
+ */
+ width: widthProp,
+ height: heightProp,
viewBox,
id,
className = '',
@@ -39,14 +65,20 @@ const SvgIcon: React.FC = ({
getRootRef,
Component = 'div',
role,
+ fontSize,
"aria-label": ariaLabel,
"aria-hidden": ariaHidden,
...restProps
}) => {
- const size = Math.max(width, height);
-
const iconSettings = React.useContext(IconSettingsContext);
- const ownClass = iconClass(['Icon', `Icon--${size}`, `Icon--w-${width}`, `Icon--h-${height}`, `Icon--${id}`], iconSettings);
+
+ const classNameWidth = widthProp || defaultWidth;
+ const classNameHeight = heightProp || defaultHeight;
+ const classNameSize = Math.max(classNameWidth, classNameHeight);
+ const ownClass = iconClass(['Icon', `Icon--${classNameSize}`, `Icon--w-${classNameWidth}`, `Icon--h-${classNameHeight}`, `Icon--${id}`], iconSettings);
+
+ const width = widthProp || relativeWidth;
+ const height = heightProp || relativeHeight;
return (
= ({
{...restProps}
ref={getRootRef}
className={`${ownClass} ${className}`}
- style={{ ...style, width, height }}
+ style={{ ...style, width, height, fontSize }}
>
- {sizeExample}
+ {sizeExampleFixSize}
Стилизация