2
0
mirror of https://github.com/iconify/iconify.git synced 2025-01-07 15:44:05 +00:00

Change iconToSVG attributes from full to partial icon and customisations

This commit is contained in:
Vjacheslav Trushkin 2022-07-01 22:12:18 +03:00
parent d475c2e3a8
commit 8eca9c6741
14 changed files with 592 additions and 375 deletions

View File

@ -13,7 +13,7 @@ import {
} from '@iconify/core/lib/storage/functions'; } from '@iconify/core/lib/storage/functions';
import { listIcons } from '@iconify/core/lib/storage/storage'; import { listIcons } from '@iconify/core/lib/storage/storage';
import type { IconifyBuilderFunctions } from '@iconify/core/lib/builder/functions'; import type { IconifyBuilderFunctions } from '@iconify/core/lib/builder/functions';
import { buildIcon } from '@iconify/core/lib/builder/functions'; import { iconToSVG as buildIcon } from '@iconify/utils/lib/svg/build';
import { replaceIDs } from '@iconify/utils/lib/svg/id'; import { replaceIDs } from '@iconify/utils/lib/svg/id';
import { calculateSize } from '@iconify/utils/lib/svg/size'; import { calculateSize } from '@iconify/utils/lib/svg/size';
import type { IconifyIconBuildResult } from '@iconify/utils/lib/svg/build'; import type { IconifyIconBuildResult } from '@iconify/utils/lib/svg/build';

View File

@ -16,7 +16,7 @@ import {
} from '@iconify/core/lib/storage/functions'; } from '@iconify/core/lib/storage/functions';
import { listIcons } from '@iconify/core/lib/storage/storage'; import { listIcons } from '@iconify/core/lib/storage/storage';
import type { IconifyBuilderFunctions } from '@iconify/core/lib/builder/functions'; import type { IconifyBuilderFunctions } from '@iconify/core/lib/builder/functions';
import { buildIcon } from '@iconify/core/lib/builder/functions'; import { iconToSVG as buildIcon } from '@iconify/utils/lib/svg/build';
import { replaceIDs } from '@iconify/utils/lib/svg/id'; import { replaceIDs } from '@iconify/utils/lib/svg/id';
import { calculateSize } from '@iconify/utils/lib/svg/size'; import { calculateSize } from '@iconify/utils/lib/svg/size';
import type { IconifyIconBuildResult } from '@iconify/utils/lib/svg/build'; import type { IconifyIconBuildResult } from '@iconify/utils/lib/svg/build';

View File

@ -15,7 +15,7 @@ import {
} from '@iconify/core/lib/storage/functions'; } from '@iconify/core/lib/storage/functions';
import { listIcons } from '@iconify/core/lib/storage/storage'; import { listIcons } from '@iconify/core/lib/storage/storage';
import type { IconifyBuilderFunctions } from '@iconify/core/lib/builder/functions'; import type { IconifyBuilderFunctions } from '@iconify/core/lib/builder/functions';
import { buildIcon } from '@iconify/core/lib/builder/functions'; import { iconToSVG as buildIcon } from '@iconify/utils/lib/svg/build';
import { replaceIDs } from '@iconify/utils/lib/svg/id'; import { replaceIDs } from '@iconify/utils/lib/svg/id';
import { calculateSize } from '@iconify/utils/lib/svg/size'; import { calculateSize } from '@iconify/utils/lib/svg/size';
import type { IconifyIconBuildResult } from '@iconify/utils/lib/svg/build'; import type { IconifyIconBuildResult } from '@iconify/utils/lib/svg/build';

View File

@ -12,7 +12,7 @@ import {
} from '@iconify/core/lib/storage/functions'; } from '@iconify/core/lib/storage/functions';
import { listIcons } from '@iconify/core/lib/storage/storage'; import { listIcons } from '@iconify/core/lib/storage/storage';
import type { IconifyBuilderFunctions } from '@iconify/core/lib/builder/functions'; import type { IconifyBuilderFunctions } from '@iconify/core/lib/builder/functions';
import { buildIcon } from '@iconify/core/lib/builder/functions'; import { iconToSVG as buildIcon } from '@iconify/utils/lib/svg/build';
import { replaceIDs } from '@iconify/utils/lib/svg/id'; import { replaceIDs } from '@iconify/utils/lib/svg/id';
import { calculateSize } from '@iconify/utils/lib/svg/size'; import { calculateSize } from '@iconify/utils/lib/svg/size';

View File

@ -12,7 +12,7 @@ import {
} from '@iconify/core/lib/storage/functions'; } from '@iconify/core/lib/storage/functions';
import { listIcons } from '@iconify/core/lib/storage/storage'; import { listIcons } from '@iconify/core/lib/storage/storage';
import type { IconifyBuilderFunctions } from '@iconify/core/lib/builder/functions'; import type { IconifyBuilderFunctions } from '@iconify/core/lib/builder/functions';
import { buildIcon } from '@iconify/core/lib/builder/functions'; import { iconToSVG as buildIcon } from '@iconify/utils/lib/svg/build';
import { replaceIDs } from '@iconify/utils/lib/svg/id'; import { replaceIDs } from '@iconify/utils/lib/svg/id';
import { calculateSize } from '@iconify/utils/lib/svg/size'; import { calculateSize } from '@iconify/utils/lib/svg/size';

View File

@ -25,7 +25,7 @@ import {
} from '@iconify/core/lib/storage/functions'; } from '@iconify/core/lib/storage/functions';
import { listIcons } from '@iconify/core/lib/storage/storage'; import { listIcons } from '@iconify/core/lib/storage/storage';
import type { IconifyBuilderFunctions } from '@iconify/core/lib/builder/functions'; import type { IconifyBuilderFunctions } from '@iconify/core/lib/builder/functions';
import { buildIcon } from '@iconify/core/lib/builder/functions'; import { iconToSVG as buildIcon } from '@iconify/utils/lib/svg/build';
import { replaceIDs } from '@iconify/utils/lib/svg/id'; import { replaceIDs } from '@iconify/utils/lib/svg/id';
import { calculateSize } from '@iconify/utils/lib/svg/size'; import { calculateSize } from '@iconify/utils/lib/svg/size';
import type { IconifyIconBuildResult } from '@iconify/utils/lib/svg/build'; import type { IconifyIconBuildResult } from '@iconify/utils/lib/svg/build';

View File

@ -18,7 +18,7 @@ import {
} from '@iconify/core/lib/storage/functions'; } from '@iconify/core/lib/storage/functions';
import { listIcons } from '@iconify/core/lib/storage/storage'; import { listIcons } from '@iconify/core/lib/storage/storage';
import type { IconifyBuilderFunctions } from '@iconify/core/lib/builder/functions'; import type { IconifyBuilderFunctions } from '@iconify/core/lib/builder/functions';
import { buildIcon } from '@iconify/core/lib/builder/functions'; import { iconToSVG as buildIcon } from '@iconify/utils/lib/svg/build';
import { replaceIDs } from '@iconify/utils/lib/svg/id'; import { replaceIDs } from '@iconify/utils/lib/svg/id';
import { calculateSize } from '@iconify/utils/lib/svg/size'; import { calculateSize } from '@iconify/utils/lib/svg/size';
import type { IconifyIconBuildResult } from '@iconify/utils/lib/svg/build'; import type { IconifyIconBuildResult } from '@iconify/utils/lib/svg/build';

View File

@ -13,7 +13,7 @@ import {
} from '@iconify/core/lib/storage/functions'; } from '@iconify/core/lib/storage/functions';
import { listIcons } from '@iconify/core/lib/storage/storage'; import { listIcons } from '@iconify/core/lib/storage/storage';
import type { IconifyBuilderFunctions } from '@iconify/core/lib/builder/functions'; import type { IconifyBuilderFunctions } from '@iconify/core/lib/builder/functions';
import { buildIcon } from '@iconify/core/lib/builder/functions'; import { iconToSVG as buildIcon } from '@iconify/utils/lib/svg/build';
import { calculateSize } from '@iconify/utils/lib/svg/size'; import { calculateSize } from '@iconify/utils/lib/svg/size';
// API // API

View File

@ -1,9 +1,5 @@
import type { IconifyIcon } from '@iconify/types'; import type { IconifyIcon } from '@iconify/types';
import { defaultIconProps } from '@iconify/utils/lib/icon/defaults';
import { defaultIconCustomisations } from '@iconify/utils/lib/customisations/defaults';
import { mergeCustomisations } from '@iconify/utils/lib/customisations/merge';
import type { IconifyIconCustomisations } from '@iconify/utils/lib/customisations/defaults'; import type { IconifyIconCustomisations } from '@iconify/utils/lib/customisations/defaults';
import { iconToSVG } from '@iconify/utils/lib/svg/build';
import type { IconifyIconBuildResult } from '@iconify/utils/lib/svg/build'; import type { IconifyIconBuildResult } from '@iconify/utils/lib/svg/build';
/** /**
@ -21,16 +17,3 @@ export interface IconifyBuilderFunctions {
customisations?: IconifyIconCustomisations customisations?: IconifyIconCustomisations
) => IconifyIconBuildResult; ) => IconifyIconBuildResult;
} }
/**
* Build icon
*/
export function buildIcon(
icon: IconifyIcon,
customisations?: IconifyIconCustomisations
): IconifyIconBuildResult {
return iconToSVG(
{ ...defaultIconProps, ...icon },
mergeCustomisations(defaultIconCustomisations, customisations || {})
);
}

View File

@ -65,6 +65,10 @@ export function getIconData(
name: string, name: string,
full: false full: false
): ExtendedIconifyIcon | null; ): ExtendedIconifyIcon | null;
export function getIconData(
data: IconifyJSON,
name: string
): ExtendedIconifyIcon | null;
export function getIconData( export function getIconData(
data: IconifyJSON, data: IconifyJSON,
name: string, name: string,

View File

@ -1,5 +1,4 @@
import type { IconifyJSON } from '@iconify/types'; import type { IconifyJSON, IconifyIcon } from '@iconify/types';
import type { FullIconifyIcon } from '../icon/defaults';
import { iconToSVG } from '../svg/build'; import { iconToSVG } from '../svg/build';
import { getIconData } from '../icon-set/get-icon'; import { getIconData } from '../icon-set/get-icon';
import { mergeIconProps } from './utils'; import { mergeIconProps } from './utils';
@ -15,10 +14,10 @@ export async function searchForIcon(
ids: string[], ids: string[],
options?: IconifyLoaderOptions options?: IconifyLoaderOptions
): Promise<string | undefined> { ): Promise<string | undefined> {
let iconData: FullIconifyIcon | null; let iconData: IconifyIcon | null;
const { customize } = options?.customizations ?? {}; const { customize } = options?.customizations ?? {};
for (const id of ids) { for (const id of ids) {
iconData = getIconData(iconSet, id, true); iconData = getIconData(iconSet, id);
if (iconData) { if (iconData) {
debug(`${collection}:${id}`); debug(`${collection}:${id}`);
let defaultCustomizations = { ...defaultIconCustomisations }; let defaultCustomizations = { ...defaultIconCustomisations };

View File

@ -1,5 +1,8 @@
import type { FullIconifyIcon } from '../icon/defaults'; import { defaultIconProps, IconifyIcon } from '../icon/defaults';
import type { FullIconCustomisations } from '../customisations/defaults'; import {
defaultIconCustomisations,
IconifyIconCustomisations,
} from '../customisations/defaults';
import { calculateSize } from './size'; import { calculateSize } from './size';
/** /**
@ -38,22 +41,31 @@ interface ViewBox {
* Use replaceIDs to generate unique IDs for body. * Use replaceIDs to generate unique IDs for body.
*/ */
export function iconToSVG( export function iconToSVG(
icon: FullIconifyIcon, icon: IconifyIcon,
customisations: FullIconCustomisations customisations?: IconifyIconCustomisations
): IconifyIconBuildResult { ): IconifyIconBuildResult {
const fullIcon = {
...defaultIconProps,
...icon,
};
const fullCustomisations = {
...defaultIconCustomisations,
...customisations,
};
// viewBox // viewBox
const box: ViewBox = { const box: ViewBox = {
left: icon.left, left: fullIcon.left,
top: icon.top, top: fullIcon.top,
width: icon.width, width: fullIcon.width,
height: icon.height, height: fullIcon.height,
}; };
// Body // Body
let body = icon.body; let body = fullIcon.body;
// Apply transformations // Apply transformations
[icon, customisations].forEach((props) => { [fullIcon, fullCustomisations].forEach((props) => {
const transformations: string[] = []; const transformations: string[] = [];
const hFlip = props.hFlip; const hFlip = props.hFlip;
const vFlip = props.vFlip; const vFlip = props.vFlip;
@ -155,8 +167,8 @@ export function iconToSVG(
}); });
// Calculate dimensions // Calculate dimensions
const customisationsWidth = customisations.width; const customisationsWidth = fullCustomisations.width;
const customisationsHeight = customisations.height; const customisationsHeight = fullCustomisations.height;
const boxWidth = box.width; const boxWidth = box.width;
const boxHeight = box.height; const boxHeight = box.height;

View File

@ -1,15 +1,12 @@
import type { IconifyIconBuildResult } from '../lib/svg/build'; import type { IconifyIconBuildResult } from '../lib/svg/build';
import { iconToSVG } from '../lib/svg/build'; import { iconToSVG } from '../lib/svg/build';
import type { FullIconifyIcon } from '../lib/icon/defaults'; import type { IconifyIcon } from '../lib/icon/defaults';
import { defaultIconProps } from '../lib/icon/defaults'; import type { IconifyIconCustomisations } from '../lib/customisations/defaults';
import type { FullIconCustomisations } from '../lib/customisations/defaults';
import { defaultIconCustomisations } from '../lib/customisations/defaults';
import { iconToHTML } from '../lib/svg/html'; import { iconToHTML } from '../lib/svg/html';
describe('Testing iconToSVG', () => { describe('Testing iconToSVG', () => {
test('Empty icon', () => { test('Empty icon', () => {
const custom: FullIconCustomisations = defaultIconCustomisations; const icon: IconifyIcon = { body: '' };
const icon: FullIconifyIcon = { ...defaultIconProps, body: '' };
const expected: IconifyIconBuildResult = { const expected: IconifyIconBuildResult = {
attributes: { attributes: {
width: '1em', width: '1em',
@ -19,7 +16,7 @@ describe('Testing iconToSVG', () => {
body: '', body: '',
}; };
const result = iconToSVG(icon, custom); const result = iconToSVG(icon);
expect(result).toEqual(expected); expect(result).toEqual(expected);
// Test HTML // Test HTML
@ -30,12 +27,10 @@ describe('Testing iconToSVG', () => {
}); });
test('Auto size, body', () => { test('Auto size, body', () => {
const custom: FullIconCustomisations = { const custom: IconifyIconCustomisations = {
...defaultIconCustomisations,
height: 'auto', height: 'auto',
}; };
const icon: FullIconifyIcon = { const icon: IconifyIcon = {
...defaultIconProps,
body: '<path d="" />', body: '<path d="" />',
}; };
const expected: IconifyIconBuildResult = { const expected: IconifyIconBuildResult = {
@ -63,12 +58,10 @@ describe('Testing iconToSVG', () => {
}); });
test('Auto size, body', () => { test('Auto size, body', () => {
const custom: FullIconCustomisations = { const custom: IconifyIconCustomisations = {
...defaultIconCustomisations,
height: 'auto', height: 'auto',
}; };
const icon: FullIconifyIcon = { const icon: IconifyIcon = {
...defaultIconProps,
body: '<path d="" />', body: '<path d="" />',
}; };
const expected: IconifyIconBuildResult = { const expected: IconifyIconBuildResult = {
@ -85,12 +78,10 @@ describe('Testing iconToSVG', () => {
}); });
test('Custom size', () => { test('Custom size', () => {
const custom: FullIconCustomisations = { const custom: IconifyIconCustomisations = {
...defaultIconCustomisations,
height: 'auto', height: 'auto',
}; };
const icon: FullIconifyIcon = { const icon: IconifyIcon = {
...defaultIconProps,
width: 20, width: 20,
height: 16, height: 16,
body: '<path d="..." />', body: '<path d="..." />',
@ -109,13 +100,11 @@ describe('Testing iconToSVG', () => {
}); });
test('Rotation', () => { test('Rotation', () => {
const custom: FullIconCustomisations = { const custom: IconifyIconCustomisations = {
...defaultIconCustomisations,
height: '40px', height: '40px',
rotate: 1, rotate: 1,
}; };
const icon: FullIconifyIcon = { const icon: IconifyIcon = {
...defaultIconProps,
width: 20, width: 20,
height: 16, height: 16,
body: '<path d="..." />', body: '<path d="..." />',
@ -134,13 +123,11 @@ describe('Testing iconToSVG', () => {
}); });
test('Negative rotation', () => { test('Negative rotation', () => {
const custom: FullIconCustomisations = { const custom: IconifyIconCustomisations = {
...defaultIconCustomisations,
height: '40px', height: '40px',
rotate: -1, rotate: -1,
}; };
const icon: FullIconifyIcon = { const icon: IconifyIcon = {
...defaultIconProps,
width: 20, width: 20,
height: 16, height: 16,
body: '<path d="..." />', body: '<path d="..." />',
@ -159,13 +146,11 @@ describe('Testing iconToSVG', () => {
}); });
test('Flip', () => { test('Flip', () => {
const custom: FullIconCustomisations = { const custom: IconifyIconCustomisations = {
...defaultIconCustomisations,
height: '32', height: '32',
hFlip: true, hFlip: true,
}; };
const icon: FullIconifyIcon = { const icon: IconifyIcon = {
...defaultIconProps,
width: 20, width: 20,
height: 16, height: 16,
body: '<path d="..." />', body: '<path d="..." />',
@ -184,13 +169,11 @@ describe('Testing iconToSVG', () => {
}); });
test('Flip, rotation', () => { test('Flip, rotation', () => {
const custom: FullIconCustomisations = { const custom: IconifyIconCustomisations = {
...defaultIconCustomisations,
hFlip: true, hFlip: true,
rotate: 1, rotate: 1,
}; };
const icon: FullIconifyIcon = { const icon: IconifyIcon = {
...defaultIconProps,
width: 20, width: 20,
height: 16, height: 16,
body: '<path d="..." />', body: '<path d="..." />',
@ -209,12 +192,10 @@ describe('Testing iconToSVG', () => {
}); });
test('Flip icon that is rotated by default', () => { test('Flip icon that is rotated by default', () => {
const custom: FullIconCustomisations = { const custom: IconifyIconCustomisations = {
...defaultIconCustomisations,
hFlip: true, hFlip: true,
}; };
const icon: FullIconifyIcon = { const icon: IconifyIcon = {
...defaultIconProps,
width: 20, width: 20,
height: 16, height: 16,
body: '<path d="..." />', body: '<path d="..." />',
@ -237,16 +218,14 @@ describe('Testing iconToSVG', () => {
}); });
test('Flip and rotation canceling eachother', () => { test('Flip and rotation canceling eachother', () => {
const custom: FullIconCustomisations = { const custom: IconifyIconCustomisations = {
...defaultIconCustomisations,
width: '1em', width: '1em',
height: 'auto', height: 'auto',
hFlip: true, hFlip: true,
vFlip: true, vFlip: true,
rotate: 2, rotate: 2,
}; };
const icon: FullIconifyIcon = { const icon: IconifyIcon = {
...defaultIconProps,
width: 20, width: 20,
height: 16, height: 16,
body: '<path d="..." />', body: '<path d="..." />',
@ -264,13 +243,11 @@ describe('Testing iconToSVG', () => {
expect(result).toEqual(expected); expect(result).toEqual(expected);
}); });
test('Flip with real icon', () => { test('Flip with icon, no customisations', () => {
const iconBody = const iconBody =
'<g stroke="currentColor" stroke-width="16" stroke-linecap="round" stroke-linejoin="round" fill="none" fill-rule="evenodd"><path d="M40 64l48-48" class="animation-delay-0 animation-duration-10 animate-stroke stroke-length-102"/><path d="M40 64l48 48" class="animation-delay-0 animation-duration-10 animate-stroke stroke-length-102"/></g>'; '<g stroke="currentColor" stroke-width="16" stroke-linecap="round" stroke-linejoin="round" fill="none" fill-rule="evenodd"><path d="M40 64l48-48" class="animation-delay-0 animation-duration-10 animate-stroke stroke-length-102"/><path d="M40 64l48 48" class="animation-delay-0 animation-duration-10 animate-stroke stroke-length-102"/></g>';
const custom: FullIconCustomisations = defaultIconCustomisations; const icon: IconifyIcon = {
const icon: FullIconifyIcon = {
...defaultIconProps,
body: iconBody, body: iconBody,
width: 128, width: 128,
height: 128, height: 128,
@ -288,7 +265,7 @@ describe('Testing iconToSVG', () => {
'</g>', '</g>',
}; };
const result = iconToSVG(icon, custom); const result = iconToSVG(icon);
expect(result).toEqual(expected); expect(result).toEqual(expected);
}); });
}); });

814
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff