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

chore(utils): add customise option to css functions, fix forceSquare

This commit is contained in:
Vjacheslav Trushkin 2024-05-06 22:08:07 +03:00
parent ca87add889
commit 7f0454faf0
6 changed files with 107 additions and 17 deletions

View File

@ -61,8 +61,21 @@ export function generateItemCSSRules(
const varName = options.varName; const varName = options.varName;
// Calculate width // Calculate width
if (!options.forceSquare && icon.width !== icon.height) { if (icon.width !== icon.height) {
result['width'] = calculateSize('1em', icon.width / icon.height); if (options.forceSquare) {
// Change viewBox
const max = Math.max(icon.width, icon.height);
icon = {
...icon,
width: max,
height: max,
left: icon.left - (max - icon.width) / 2,
top: icon.top - (max - icon.height) / 2,
};
} else {
// Change width in result
result['width'] = calculateSize('1em', icon.width / icon.height);
}
} }
// Get SVG // Get SVG

View File

@ -15,10 +15,13 @@ export function getIconCSS(
icon: IconifyIcon, icon: IconifyIcon,
options: IconCSSIconOptions = {} options: IconCSSIconOptions = {}
): string { ): string {
// Get body
const body = options.customise ? options.customise(icon.body) : icon.body;
// Get mode // Get mode
const mode = const mode =
options.mode || options.mode ||
(options.color || !icon.body.includes('currentColor') (options.color || !body.includes('currentColor')
? 'background' ? 'background'
: 'mask'); : 'mask');
@ -44,7 +47,14 @@ export function getIconCSS(
const rules = { const rules = {
...options.rules, ...options.rules,
...getCommonCSSRules(newOptions), ...getCommonCSSRules(newOptions),
...generateItemCSSRules({ ...defaultIconProps, ...icon }, newOptions), ...generateItemCSSRules(
{
...defaultIconProps,
...icon,
body,
},
newOptions
),
}; };
// Get selector and format CSS // Get selector and format CSS
@ -67,9 +77,16 @@ export function getIconContentCSS(
icon: IconifyIcon, icon: IconifyIcon,
options: IconContentIconOptions options: IconContentIconOptions
): string { ): string {
// Get body
const body = options.customise ? options.customise(icon.body) : icon.body;
// Get content // Get content
const content = generateItemContent( const content = generateItemContent(
{ ...defaultIconProps, ...icon }, {
...defaultIconProps,
...icon,
body,
},
options options
); );

View File

@ -42,18 +42,20 @@ export function getIconsCSSData(
const errors: string[] = []; const errors: string[] = [];
// Get mode // Get mode
const palette = options.color ? true : iconSet.info?.palette; const palette = options.color ? true : undefined;
let mode = let mode =
options.mode || options.mode ||
(typeof palette === 'boolean' && (palette ? 'background' : 'mask')); (typeof palette === 'boolean' && (palette ? 'background' : 'mask'));
if (!mode) { if (!mode) {
// Attempt to detect mode from first available icon // Attempt to detect mode from first available icon
for (let i = 0; i < names.length; i++) { for (let i = 0; i < names.length; i++) {
const icon = getIconData(iconSet, names[i]); const name = names[i];
const icon = getIconData(iconSet, name);
if (icon) { if (icon) {
mode = icon.body.includes('currentColor') const body = options.customise
? 'mask' ? options.customise(icon.body, name)
: 'background'; : icon.body;
mode = body.includes('currentColor') ? 'mask' : 'background';
break; break;
} }
} }
@ -114,10 +116,14 @@ export function getIconsCSSData(
continue; continue;
} }
const body = options.customise
? options.customise(iconData.body, name)
: iconData.body;
const rules = generateItemCSSRules( const rules = generateItemCSSRules(
{ {
...defaultIconProps, ...defaultIconProps,
...iconData, ...iconData,
body,
}, },
newOptions newOptions
); );
@ -220,8 +226,15 @@ export function getIconsContentCSS(
continue; continue;
} }
const body = options.customise
? options.customise(iconData.body, name)
: iconData.body;
const content = generateItemContent( const content = generateItemContent(
{ ...defaultIconProps, ...iconData }, {
...defaultIconProps,
...iconData,
body,
},
options options
); );
const selector = iconSelectorWithPrefix.replace(/{name}/g, name); const selector = iconSelectorWithPrefix.replace(/{name}/g, name);

View File

@ -159,7 +159,8 @@ export interface IconCSSIconOptions
IconCSSIconSelectorOptions, IconCSSIconSelectorOptions,
IconCSSModeOptions, IconCSSModeOptions,
IconCSSFormatOptions { IconCSSFormatOptions {
// // Customise icon
customise?: (content: string) => string;
} }
/** /**
@ -169,7 +170,8 @@ export interface IconContentIconOptions
extends IconContentSharedOptions, extends IconContentSharedOptions,
IconContentIconSelectorOptions, IconContentIconSelectorOptions,
IconCSSFormatOptions { IconCSSFormatOptions {
// // Customise icon
customise?: (content: string) => string;
} }
/** /**
@ -180,7 +182,8 @@ export interface IconCSSIconSetOptions
IconCSSSelectorOptions, IconCSSSelectorOptions,
IconCSSModeOptions, IconCSSModeOptions,
IconCSSFormatOptions { IconCSSFormatOptions {
// // Customise icon from icon set
customise?: (content: string, name: string) => string;
} }
/** /**
@ -190,5 +193,6 @@ export interface IconContentIconSetOptions
extends IconContentSharedOptions, extends IconContentSharedOptions,
IconContentIconSelectorOptions, IconContentIconSelectorOptions,
IconCSSFormatOptions { IconCSSFormatOptions {
// // Customise icon from icon set
customise?: (content: string, name: string) => string;
} }

View File

@ -35,7 +35,10 @@ describe('Testing CSS for icon', () => {
height: 16, height: 16,
}; };
const expectedURL = svgToURL( const expectedURL = svgToURL(
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 16" width="24" height="16">${icon.body}</svg>` `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -4 24 24" width="24" height="24">${icon.body.replace(
'f80',
'fff'
)}</svg>`
); );
expect( expect(
@ -48,6 +51,7 @@ describe('Testing CSS for icon', () => {
rules: { rules: {
visibility: 'visible', visibility: 'visible',
}, },
customise: (content) => content.replace('f80', 'fff'),
}) })
).toBe(`.test-icon:after { ).toBe(`.test-icon:after {
visibility: visible; visibility: visible;
@ -104,6 +108,7 @@ describe('Testing CSS for icon', () => {
)}</svg>` )}</svg>`
); );
// Use color option
expect( expect(
getIconCSS(icon, { getIconCSS(icon, {
format: 'expanded', format: 'expanded',
@ -117,6 +122,23 @@ describe('Testing CSS for icon', () => {
background-size: 100% 100%; background-size: 100% 100%;
background-image: ${expectedURL}; background-image: ${expectedURL};
} }
`);
// Use customise option
expect(
getIconCSS(icon, {
format: 'expanded',
customise: (content) =>
content.replace(/currentColor/g, 'purple'),
})
).toBe(`.icon {
display: inline-block;
width: 1em;
height: 1em;
background-repeat: no-repeat;
background-size: 100% 100%;
background-image: ${expectedURL};
}
`); `);
}); });

View File

@ -73,6 +73,9 @@ describe('Testing CSS for multiple icons', () => {
getIconsCSS(iconSet, ['123'], { getIconsCSS(iconSet, ['123'], {
format: 'expanded', format: 'expanded',
mode: 'background', mode: 'background',
// Swap content
customise: (content, name) =>
name === '123' ? iconSet.icons['airplane'].body : content,
}) })
).toBe(`.icon--test-prefix { ).toBe(`.icon--test-prefix {
display: inline-block; display: inline-block;
@ -83,7 +86,7 @@ describe('Testing CSS for multiple icons', () => {
} }
.icon--test-prefix--123 { .icon--test-prefix--123 {
background-image: ${expectedURL('123')}; background-image: ${expectedURL('airplane')};
} }
`); `);
@ -104,6 +107,24 @@ describe('Testing CSS for multiple icons', () => {
.icon--test-prefix--empty { .icon--test-prefix--empty {
background-image: ${expectedURL('empty', 'red')}; background-image: ${expectedURL('empty', 'red')};
} }
`);
expect(
getIconsCSS(iconSet, ['activity'], {
format: 'expanded',
customise: (content) => content.replace(/currentColor/g, 'red'),
})
).toBe(`.icon--test-prefix {
display: inline-block;
width: 1em;
height: 1em;
background-repeat: no-repeat;
background-size: 100% 100%;
}
.icon--test-prefix--activity {
background-image: ${expectedURL('activity', 'red')};
}
`); `);
}); });