mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-12-05 12:04:45 +01:00
refactor: Convert icon manager into class
This commit is contained in:
@@ -23,10 +23,11 @@ export const unknownIcon: IconifyIcon = {
|
||||
width: 80,
|
||||
};
|
||||
|
||||
const iconsStore = new Map<string, IconifyJSON>();
|
||||
const loaderStore = new Map<string, AsyncIconLoader['loader']>();
|
||||
class IconManager {
|
||||
private iconsStore = new Map<string, IconifyJSON>();
|
||||
private loaderStore = new Map<string, AsyncIconLoader['loader']>();
|
||||
|
||||
export const registerIconPacks = (iconLoaders: IconLoader[]) => {
|
||||
registerIconPacks(iconLoaders: IconLoader[]): void {
|
||||
for (const iconLoader of iconLoaders) {
|
||||
if (!iconLoader.name) {
|
||||
throw new Error(
|
||||
@@ -35,17 +36,20 @@ export const registerIconPacks = (iconLoaders: IconLoader[]) => {
|
||||
}
|
||||
log.debug('Registering icon pack:', iconLoader.name);
|
||||
if ('loader' in iconLoader) {
|
||||
loaderStore.set(iconLoader.name, iconLoader.loader);
|
||||
this.loaderStore.set(iconLoader.name, iconLoader.loader);
|
||||
} else if ('icons' in iconLoader) {
|
||||
iconsStore.set(iconLoader.name, iconLoader.icons);
|
||||
this.iconsStore.set(iconLoader.name, iconLoader.icons);
|
||||
} else {
|
||||
log.error('Invalid icon loader:', iconLoader);
|
||||
throw new Error('Invalid icon loader. Must have either "icons" or "loader" property.');
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const getRegisteredIconData = async (iconName: string, fallbackPrefix?: string) => {
|
||||
private async getRegisteredIconData(
|
||||
iconName: string,
|
||||
fallbackPrefix?: string
|
||||
): Promise<ExtendedIconifyIcon> {
|
||||
const data = stringToIcon(iconName, true, fallbackPrefix !== undefined);
|
||||
if (!data) {
|
||||
throw new Error(`Invalid icon name: ${iconName}`);
|
||||
@@ -54,16 +58,16 @@ const getRegisteredIconData = async (iconName: string, fallbackPrefix?: string)
|
||||
if (!prefix) {
|
||||
throw new Error(`Icon name must contain a prefix: ${iconName}`);
|
||||
}
|
||||
let icons = iconsStore.get(prefix);
|
||||
let icons = this.iconsStore.get(prefix);
|
||||
if (!icons) {
|
||||
const loader = loaderStore.get(prefix);
|
||||
const loader = this.loaderStore.get(prefix);
|
||||
if (!loader) {
|
||||
throw new Error(`Icon set not found: ${data.prefix}`);
|
||||
}
|
||||
try {
|
||||
const loaded = await loader();
|
||||
icons = { ...loaded, prefix };
|
||||
iconsStore.set(prefix, icons);
|
||||
this.iconsStore.set(prefix, icons);
|
||||
} catch (e) {
|
||||
log.error(e);
|
||||
throw new Error(`Failed to load icon set: ${data.prefix}`);
|
||||
@@ -74,25 +78,25 @@ const getRegisteredIconData = async (iconName: string, fallbackPrefix?: string)
|
||||
throw new Error(`Icon not found: ${iconName}`);
|
||||
}
|
||||
return iconData;
|
||||
};
|
||||
}
|
||||
|
||||
export const isIconAvailable = async (iconName: string) => {
|
||||
async isIconAvailable(iconName: string): Promise<boolean> {
|
||||
try {
|
||||
await getRegisteredIconData(iconName);
|
||||
await this.getRegisteredIconData(iconName);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export const getIconSVG = async (
|
||||
async getIconSVG(
|
||||
iconName: string,
|
||||
customisations?: IconifyIconCustomisations & { fallbackPrefix?: string },
|
||||
extraAttributes?: Record<string, string>
|
||||
) => {
|
||||
): Promise<string> {
|
||||
let iconData: ExtendedIconifyIcon;
|
||||
try {
|
||||
iconData = await getRegisteredIconData(iconName, customisations?.fallbackPrefix);
|
||||
iconData = await this.getRegisteredIconData(iconName, customisations?.fallbackPrefix);
|
||||
} catch (e) {
|
||||
log.error(e);
|
||||
iconData = unknownIcon;
|
||||
@@ -103,4 +107,22 @@ export const getIconSVG = async (
|
||||
...extraAttributes,
|
||||
});
|
||||
return sanitizeText(svg, getConfig());
|
||||
}
|
||||
}
|
||||
|
||||
const globalIconManager = new IconManager();
|
||||
|
||||
// Export the singleton instance methods for backward compatibility
|
||||
export const registerIconPacks = (iconLoaders: IconLoader[]) =>
|
||||
globalIconManager.registerIconPacks(iconLoaders);
|
||||
export const isIconAvailable = async (iconName: string) => {
|
||||
return await globalIconManager.isIconAvailable(iconName);
|
||||
};
|
||||
|
||||
export const getIconSVG = async (
|
||||
iconName: string,
|
||||
customisations?: IconifyIconCustomisations & { fallbackPrefix?: string },
|
||||
extraAttributes?: Record<string, string>
|
||||
) => {
|
||||
return await globalIconManager.getIconSVG(iconName, customisations, extraAttributes);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user