This NPM module is meant to be used in conjunction with onyxia-ui
The idea behind it is to be ables to use the @mui/icons-material
catalog of icons even if
the icons that will be used aren't known at build time.
Since including all 2000+ icons in the bundle would make the bundle size explode there is a need for a solution that enables to load the icons lazily when they are needed.
It's a requirement we have for the Onyxia project because the web application is distributed as a white-labeled
statical SPA. People that deploy an onyxia instance can customize the look of onyxia via injecting standardized
environnement variable.
This means that we can't know at build time which icons will be used.
yarn add mui-icons-material-lazy
package.json
{
"scripts": {
"postinstall": "mui-icons-material-lazy postinstall"
// If you are in a monorepo you can specify your SPA (Vite or CRA) project path like:
// "postinstall": "mui-icons-material-lazy postinstall --project packages/front
}
}
import { createGetIconUrl } from "mui-icons-material-lazy";
const { getIconUrl, getIconUrlByName } = createGetIconUrl({
BASE_URL: import.meta.env.BASE_URL
// Or if you are in create-react-app:
// BASE_URL: process.env.PUBLIC_URL,
// Or if you have a custom build setup:
// BASE_URL: "/",
});
// Let's say we have this variable that isn't known at build time:
declare const HOME_ICON: string | undefined;
getIconUrl(HOME_ICON); // The return type is `string | undefined`
// If HOME_ICON is "https://example.net/my-icon.svg": "https://example.net/my-icon.svg"
// If HOME_ICON is "Home" or "home": "https://my-app.com/mui-icons-material/Home.svg"
// Implementing fallback:
// iconUrl is of type `string`
const iconUrl = getIconUrl(HOME_ICON) ?? getIconUrlByName("Home");
src/theme.tsx
import { createOnyxiaUi } from "onyxia-ui";
import { createGetIconUrl } from "mui-icons-material-lazy";
const { OnyxiaUi, ofTypeTheme } = createOnyxiaUi({});
export { OnyxiaUi };
export type Theme = typeof ofTypeTheme;
export const { getIconUrl, getIconUrlByName } = createGetIconUrl({
BASE_URL: import.meta.env.BASE_URL
});
In a component:
import { Icon } from "onyxia-ui/Icon";
import { getIconUrl, getIconUrlByName } from "theme";
declare const SOME_ICON: string;
<Icon icon={getIconUrl(SOME_ICON)} />;
declare const MAYBE_SOME_ICON: string | undefined;
<Icon icon={getIconUrl(MAYBE_SOME_ICON) ?? getIconUrlByName("Home")} />;