Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v5] Icon component loading implementation does not account for preloaded icons #6152

Closed
Tracked by #6151
adidahiya opened this issue May 12, 2023 · 1 comment
Closed
Tracked by #6151

Comments

@adidahiya
Copy link
Contributor

Environment

  • Package version(s): core v5.0.0-alpha.3, icons v5.0.0-alpha.2
  • Operating System: macOS
  • Browser name and version: Chrome

Code Sandbox

https://codesandbox.io/p/sandbox/naughty-diffie-wy0ojy?file=%2Fsrc%2Fmain.tsx%3A36%2C4

Steps to reproduce

Found this while trying to upgrade the sandbox to v5.0.0-alpha in #6151

I attempted to implement icon loading in a non-webpack bundler environment:

// see https://vitejs.dev/guide/features.html#glob-import
const iconModules: Record<string, { default: IconComponent }> =
  import.meta.glob(
    "../node_modules/@blueprintjs/icons/lib/esm/generated/components/*.js",
    {
      eager: true,
    }
  );

console.warn(iconModules);

// specify a custom loader function for Vite
// see https://vitejs.dev/guide/features.html#dynamic-import
Icons.loadAll({
  loader: async (name) => {
    return iconModules[
      `../node_modules/@blueprintjs/icons/lib/esm/generated/components/${name}.js`
    ].default;
  },
});

Actual behavior

<Icon> component attempts to load every icon but does not know about the special loading options which were already used in Icons.loadAll. It then fails to load icons dynamically, even though they have already been loaded into the singleton:

image

Expected behavior

If icons are loaded already (like with the above snippet), <Icon> should not attempt to load them again (with a faulty loader).

It would also be nice if <Icon> accepted dynamic loading options via React context.

@adidahiya
Copy link
Contributor Author

#6158 did help, but now there's a race condition. <Icon> components can get mounted on the page before icon loading completes, in which case they will again try to load icons with the default loader since autoLoad={true} by default.

Users can work around this by waiting for the Icons.loadAll() promise to fulfill:

// specify a custom loader function for Vite
// see https://vitejs.dev/guide/features.html#dynamic-import
await Icons.loadAll({
  loader: async (name) => {
    return iconModules[
      `../node_modules/@blueprintjs/icons/lib/esm/generated/components/${name}.js`
    ].default;
  },
});

// continue to render the app only after icons have loaded
ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById("root")
);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant