diff --git a/packages/utils/src/css/common.ts b/packages/utils/src/css/common.ts
index 66e1de5..e7b2bdc 100644
--- a/packages/utils/src/css/common.ts
+++ b/packages/utils/src/css/common.ts
@@ -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
diff --git a/packages/utils/src/css/icon.ts b/packages/utils/src/css/icon.ts
index bd58daf..06a5017 100644
--- a/packages/utils/src/css/icon.ts
+++ b/packages/utils/src/css/icon.ts
@@ -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
);
diff --git a/packages/utils/src/css/icons.ts b/packages/utils/src/css/icons.ts
index b4a2146..e2b3042 100644
--- a/packages/utils/src/css/icons.ts
+++ b/packages/utils/src/css/icons.ts
@@ -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);
diff --git a/packages/utils/src/css/types.ts b/packages/utils/src/css/types.ts
index a364fd8..4d41e67 100644
--- a/packages/utils/src/css/types.ts
+++ b/packages/utils/src/css/types.ts
@@ -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;
}
diff --git a/packages/utils/tests/icon-to-css-test.ts b/packages/utils/tests/icon-to-css-test.ts
index d4a5a40..037d59f 100644
--- a/packages/utils/tests/icon-to-css-test.ts
+++ b/packages/utils/tests/icon-to-css-test.ts
@@ -35,7 +35,10 @@ describe('Testing CSS for icon', () => {
height: 16,
};
const expectedURL = svgToURL(
- ``
+ ``
);
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', () => {
)}`
);
+ // 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};
+}
`);
});
diff --git a/packages/utils/tests/icons-to-css-test.ts b/packages/utils/tests/icons-to-css-test.ts
index 39fa4fd..73298ef 100644
--- a/packages/utils/tests/icons-to-css-test.ts
+++ b/packages/utils/tests/icons-to-css-test.ts
@@ -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')};
+}
`);
});