Merge pull request #2025 from umbraco/v14/feature/allow-dynamic-import-of-icon
Feature: Allow dynamic import of icon for easier bundling
This commit is contained in:
@@ -46,7 +46,7 @@ const collectDictionaryIcons = async () => {
|
||||
legacy: iconDef.legacy,
|
||||
fileName: iconFileName,
|
||||
svg,
|
||||
output: `${iconsOutputDirectory}/${iconFileName}.js`,
|
||||
output: `${iconsOutputDirectory}/${iconFileName}.ts`,
|
||||
};
|
||||
|
||||
icons.push(icon);
|
||||
@@ -77,7 +77,7 @@ const collectDictionaryIcons = async () => {
|
||||
legacy: iconDef.legacy,
|
||||
fileName: iconFileName,
|
||||
svg,
|
||||
output: `${iconsOutputDirectory}/${iconFileName}.js`,
|
||||
output: `${iconsOutputDirectory}/${iconFileName}.ts`,
|
||||
};
|
||||
|
||||
icons.push(icon);
|
||||
@@ -102,7 +102,7 @@ const collectDictionaryIcons = async () => {
|
||||
legacy: iconDef.legacy,
|
||||
fileName: iconFileName,
|
||||
svg,
|
||||
output: `${iconsOutputDirectory}/${iconFileName}.js`,
|
||||
output: `${iconsOutputDirectory}/${iconFileName}.ts`,
|
||||
};
|
||||
|
||||
icons.push(icon);
|
||||
@@ -141,7 +141,7 @@ const collectDiskIcons = async (icons) => {
|
||||
legacy: true,
|
||||
fileName: iconFileName,
|
||||
svg,
|
||||
output: `${iconsOutputDirectory}/${iconFileName}.js`,
|
||||
output: `${iconsOutputDirectory}/${iconFileName}.ts`,
|
||||
};
|
||||
|
||||
icons.push(icon);
|
||||
@@ -168,13 +168,13 @@ const writeIconsToDisk = (icons) => {
|
||||
};
|
||||
|
||||
const generateJS = (icons) => {
|
||||
const JSPath = `${iconsOutputDirectory}/icons.ts`;
|
||||
const JSPath = `${moduleDirectory}/icons.ts`;
|
||||
|
||||
const iconDescriptors = icons.map((icon) => {
|
||||
return `{
|
||||
name: "${icon.name}",
|
||||
${icon.legacy ? 'legacy: true,' : ''}
|
||||
path: "./icons/${icon.fileName}.js",
|
||||
path: () => import("./icons/${icon.fileName}.js"),
|
||||
}`.replace(/\t/g, ''); // Regex removes white space [NL]
|
||||
});
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import type { JsLoaderProperty } from '../types/utils.js';
|
||||
|
||||
export async function loadManifestPlainJs<JsType extends object>(
|
||||
property: JsLoaderProperty<JsType>,
|
||||
): Promise<JsType | undefined> {
|
||||
export async function loadManifestPlainJs<JsType>(property: JsLoaderProperty<JsType>): Promise<JsType | undefined> {
|
||||
const propType = typeof property;
|
||||
if (propType === 'function') {
|
||||
// Promise function
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
import type { UmbIconDefinition, UmbIconModule } from './types.js';
|
||||
import { loadManifestPlainJs } from '@umbraco-cms/backoffice/extension-api';
|
||||
import { type UUIIconHost, UUIIconRegistry } from '@umbraco-cms/backoffice/external/uui';
|
||||
|
||||
interface UmbIconDescriptor {
|
||||
name: string;
|
||||
path: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @export
|
||||
* @class UmbIconRegistry
|
||||
@@ -17,10 +14,10 @@ export class UmbIconRegistry extends UUIIconRegistry {
|
||||
this.#initResolve = resolve;
|
||||
});
|
||||
|
||||
#icons: UmbIconDescriptor[] = [];
|
||||
#icons: UmbIconDefinition[] = [];
|
||||
#unhandledProviders: Map<string, UUIIconHost> = new Map();
|
||||
|
||||
setIcons(icons: UmbIconDescriptor[]) {
|
||||
setIcons(icons: UmbIconDefinition[]) {
|
||||
const oldIcons = this.#icons;
|
||||
this.#icons = icons;
|
||||
if (this.#initResolve) {
|
||||
@@ -39,7 +36,7 @@ export class UmbIconRegistry extends UUIIconRegistry {
|
||||
}
|
||||
});
|
||||
}
|
||||
appendIcons(icons: UmbIconDescriptor[]) {
|
||||
appendIcons(icons: UmbIconDefinition[]) {
|
||||
this.#icons = [...this.#icons, ...icons];
|
||||
}
|
||||
/**
|
||||
@@ -56,22 +53,22 @@ export class UmbIconRegistry extends UUIIconRegistry {
|
||||
|
||||
async #loadIcon(iconName: string, iconProvider: UUIIconHost): Promise<boolean> {
|
||||
await this.#init;
|
||||
const iconManifest = this.#icons.find((i: UmbIconDescriptor) => i.name === iconName);
|
||||
const iconManifest = this.#icons.find((i: UmbIconDefinition) => i.name === iconName);
|
||||
// Icon not found, so lets add it to a list of unhandled requests.
|
||||
if (!iconManifest) {
|
||||
this.#unhandledProviders.set(iconName, iconProvider);
|
||||
return false;
|
||||
}
|
||||
|
||||
const iconPath = iconManifest.path;
|
||||
try {
|
||||
const iconModule = await loadManifestPlainJs<UmbIconModule>(iconManifest.path);
|
||||
if (!iconModule) throw new Error(`Failed to load icon ${iconName}`);
|
||||
if (!iconModule.default) throw new Error(`Icon ${iconName} is missing a default export`);
|
||||
iconProvider.svg = iconModule.default;
|
||||
} catch (error: any) {
|
||||
console.error(`Failed to load icon ${iconName}`, error.message);
|
||||
}
|
||||
|
||||
import(/* @vite-ignore */ iconPath)
|
||||
.then((iconModule) => {
|
||||
iconProvider.svg = iconModule.default;
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(`Failed to load icon ${iconName} on path ${iconPath}`, err.message);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Meta, Story } from '@storybook/web-components';
|
||||
import icons from './icons/icons.js';
|
||||
import icons from './icons.js';
|
||||
import { html, repeat } from '@umbraco-cms/backoffice/external/lit';
|
||||
|
||||
export default {
|
||||
|
||||
2493
src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons.ts
Normal file
2493
src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons.ts
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user