2
0
mirror of https://github.com/iconify/iconify.git synced 2024-09-19 16:59:02 +00:00

Fix custom dimensions when rendering span in components

This commit is contained in:
Vjacheslav Trushkin 2022-05-01 22:12:46 +03:00
parent 1c17fa6e42
commit cee3b6eafe
7 changed files with 108 additions and 8 deletions

View File

@ -41,6 +41,13 @@ for (const prefix in propsToAddTo) {
} }
} }
/**
* Fix size: add 'px' to numbers
*/
function fixSize(value: string): string {
return value + (value.match(/^[-0-9.]+$/) ? 'px' : '');
}
/** /**
* Render icon as inline SVG * Render icon as inline SVG
*/ */
@ -78,8 +85,8 @@ export function renderBackground(
const url = svgToURL(html); const url = svgToURL(html);
const newStyles: Record<string, string> = { const newStyles: Record<string, string> = {
'--svg': url, '--svg': url,
'width': renderAttribs.width, 'width': fixSize(renderAttribs.width),
'height': renderAttribs.height, 'height': fixSize(renderAttribs.height),
...commonProps, ...commonProps,
...(useMask ? monotoneProps : coloredProps), ...(useMask ? monotoneProps : coloredProps),
}; };

View File

@ -167,4 +167,16 @@ describe('Testing rendering nodes as background', () => {
expect(data.addedClasses).toEqual(['iconify--test']); expect(data.addedClasses).toEqual(['iconify--test']);
expect(data.addedStyles).toEqual([...expectedBackgroundStyles]); expect(data.addedStyles).toEqual([...expectedBackgroundStyles]);
}); });
it('Custom dimensions', async () => {
await testIcon(
'<span class="iconify" data-icon="mdi:home" data-width="auto" data-height="48"></span>',
{
body: '<g />',
width: 24,
height: 24,
},
`<span class="iconify iconify--mdi" data-icon="mdi:home" data-width="auto" data-height="48" style="--svg: url(&quot;data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cg /%3E%3C/svg%3E&quot;); width: 24px; height: 48px; display: inline-block; background-color: transparent; background-repeat: no-repeat; background-size: 100% 100%;"></span>`
);
});
}); });

View File

@ -62,6 +62,13 @@ for (const prefix in propsToAddTo) {
*/ */
const inlineDefaults: FullIconCustomisations = { ...defaults, inline: true }; const inlineDefaults: FullIconCustomisations = { ...defaults, inline: true };
/**
* Fix size: add 'px' to numbers
*/
function fixSize(value: string): string {
return value + (value.match(/^[-0-9.]+$/) ? 'px' : '');
}
/** /**
* Render icon * Render icon
*/ */
@ -216,8 +223,8 @@ export const render = (
componentProps.style = { componentProps.style = {
...style, ...style,
'--svg': svgToURL(html), '--svg': svgToURL(html),
'width': renderAttribs.width, 'width': fixSize(renderAttribs.width),
'height': renderAttribs.height, 'height': fixSize(renderAttribs.height),
...commonProps, ...commonProps,
...(useMask ? monotoneProps : coloredProps), ...(useMask ? monotoneProps : coloredProps),
...customStyle, ...customStyle,

View File

@ -42,4 +42,40 @@ describe('Rendering as span', () => {
children: null, children: null,
}); });
}); });
test('custom dimensions', () => {
const component = renderer.create(
<Icon
icon={iconData}
mode="style"
width="32"
height={48}
onLoad={() => {
// Should be called only for icons loaded from API
throw new Error('onLoad called for object!');
}}
/>
);
const tree = component.toJSON();
expect(tree).toMatchObject({
type: 'span',
props: {
style: {
'--svg': `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath d='M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z' fill='currentColor'/%3E%3C/svg%3E")`,
'width': '32px',
'height': '48px',
'display': 'inline-block',
'backgroundColor': 'currentColor',
'webkitMaskImage': 'var(--svg)',
'webkitMaskRepeat': 'no-repeat',
'webkitMaskSize': '100% 100%',
'maskImage': 'var(--svg)',
'maskRepeat': 'no-repeat',
'maskSize': '100% 100%',
},
},
children: null,
});
});
}); });

View File

@ -54,6 +54,13 @@ for (const prefix in propsToAddTo) {
} }
} }
/**
* Fix size: add 'px' to numbers
*/
function fixSize(value: string): string {
return value + (value.match(/^[-0-9.]+$/) ? 'px' : '');
}
/** /**
* Result * Result
*/ */
@ -217,8 +224,8 @@ export function render(
const url = svgToURL(html); const url = svgToURL(html);
const styles: Record<string, string> = { const styles: Record<string, string> = {
'--svg': url, '--svg': url,
'width': renderAttribs.width, 'width': fixSize(renderAttribs.width),
'height': renderAttribs.height, 'height': fixSize(renderAttribs.height),
...commonProps, ...commonProps,
...(useMask ? monotoneProps : coloredProps), ...(useMask ? monotoneProps : coloredProps),
}; };

View File

@ -32,4 +32,28 @@ describe('Rendering as span', () => {
"<span style=\"--svg: url(&quot;data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath d='M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z' fill='currentColor'/%3E%3C/svg%3E&quot;); width: 1em; height: 1em; display: inline-block; background-color: currentColor; mask-image: var(--svg); mask-repeat: no-repeat; mask-size: 100% 100%;\"></span>" "<span style=\"--svg: url(&quot;data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath d='M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z' fill='currentColor'/%3E%3C/svg%3E&quot;); width: 1em; height: 1em; display: inline-block; background-color: currentColor; mask-image: var(--svg); mask-repeat: no-repeat; mask-size: 100% 100%;\"></span>"
); );
}); });
test('custom dimensions', () => {
const component = render(Icon, {
icon: iconData,
mode: 'style',
width: '48',
height: 32,
onLoad: () => {
// Should be called only for icons loaded from API
throw new Error('onLoad called for object!');
},
});
const node = component.container.querySelector(
'span'
) as HTMLSpanElement;
expect(node).not.toBeNull();
expect(node.parentNode).not.toBeNull();
const html = node.outerHTML;
// Check HTML
expect(html).toBe(
"<span style=\"--svg: url(&quot;data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath d='M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z' fill='currentColor'/%3E%3C/svg%3E&quot;); width: 48px; height: 32px; display: inline-block; background-color: currentColor; mask-image: var(--svg); mask-repeat: no-repeat; mask-size: 100% 100%;\"></span>"
);
});
}); });

View File

@ -83,6 +83,13 @@ const customisationAliases: Record<string, string> = {};
*/ */
type VStyle = Record<string, unknown>; type VStyle = Record<string, unknown>;
/**
* Fix size: add 'px' to numbers
*/
function fixSize(value: string): string {
return value + (value.match(/^[-0-9.]+$/) ? 'px' : '');
}
/** /**
* Render icon * Render icon
*/ */
@ -232,8 +239,8 @@ export const render = (
componentProps.style = { componentProps.style = {
...style, ...style,
'--svg': svgToURL(html), '--svg': svgToURL(html),
'width': renderAttribs.width, 'width': fixSize(renderAttribs.width),
'height': renderAttribs.height, 'height': fixSize(renderAttribs.height),
...commonProps, ...commonProps,
...(useMask ? monotoneProps : coloredProps), ...(useMask ? monotoneProps : coloredProps),
...customStyle, ...customStyle,