2
0
mirror of https://github.com/iconify/iconify.git synced 2024-06-18 14:42:21 +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;
// Calculate width
if (!options.forceSquare && icon.width !== icon.height) {
result['width'] = calculateSize('1em', icon.width / icon.height);
if (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

View File

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

View File

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

View File

@ -159,7 +159,8 @@ export interface IconCSSIconOptions
IconCSSIconSelectorOptions,
IconCSSModeOptions,
IconCSSFormatOptions {
//
// Customise icon
customise?: (content: string) => string;
}
/**
@ -169,7 +170,8 @@ export interface IconContentIconOptions
extends IconContentSharedOptions,
IconContentIconSelectorOptions,
IconCSSFormatOptions {
//
// Customise icon
customise?: (content: string) => string;
}
/**
@ -180,7 +182,8 @@ export interface IconCSSIconSetOptions
IconCSSSelectorOptions,
IconCSSModeOptions,
IconCSSFormatOptions {
//
// Customise icon from icon set
customise?: (content: string, name: string) => string;
}
/**
@ -190,5 +193,6 @@ export interface IconContentIconSetOptions
extends IconContentSharedOptions,
IconContentIconSelectorOptions,
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,
};
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(
@ -48,6 +51,7 @@ describe('Testing CSS for icon', () => {
rules: {
visibility: 'visible',
},
customise: (content) => content.replace('f80', 'fff'),
})
).toBe(`.test-icon:after {
visibility: visible;
@ -104,6 +108,7 @@ describe('Testing CSS for icon', () => {
)}</svg>`
);
// Use color option
expect(
getIconCSS(icon, {
format: 'expanded',
@ -117,6 +122,23 @@ describe('Testing CSS for icon', () => {
background-size: 100% 100%;
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'], {
format: 'expanded',
mode: 'background',
// Swap content
customise: (content, name) =>
name === '123' ? iconSet.icons['airplane'].body : content,
})
).toBe(`.icon--test-prefix {
display: inline-block;
@ -83,7 +86,7 @@ describe('Testing CSS for multiple icons', () => {
}
.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 {
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')};
}
`);
});