tailwindlabs / heroicons

A set of free MIT-licensed high-quality SVG icons for UI development.
https://heroicons.com
MIT License
21.03k stars 1.27k forks source link

Export iconNames array and names type #859

Closed mattfelten closed 1 year ago

mattfelten commented 1 year ago

I updated the build script to include an iconNames array. I really want to do something like this:

import { iconNames } from '@heroicons/react/20/solid';

export const Icon = ({ name }) => {
  const ActualIcon = React.lazy(() => import(`@heroicons/react/20/solid/${name}.js`));

  return (
    <Suspense fallback={null}>
      <ActualIcon />
    </Suspense>
  );
};

Icon.propTypes = {
    name: PropTypes.oneOf(iconNames)
};

I also made iconNamesType so someone could do the same thing with TypeScript.

import { iconNamesType } from '@heroicons/react/20/solid';

export const Icon = ({ name: iconNamesType }) => {
  const ActualIcon = React.lazy(() => import(`@heroicons/react/20/solid/${name}.js`));

  return (
    <Suspense fallback={null}>
      <ActualIcon />
    </Suspense>
  );
};

I'm pretty sure the CJS type is the same format as ESM, but I could be wrong there.

Solves https://github.com/tailwindlabs/heroicons/discussions/813. In my case (not using TS), if I did something like the suggested code from that discussion, the entire library would always be bundled.

reinink commented 1 year ago

Hey!

Thanks for this contribution, but I think for now we're just going to leave this how it is. While the approach you're suggesting would work with code splitting, you'd end up getting a unique request for every icon on the page, and without code splitting you'd end up with all the icons in your bundle.

Also, while not totally the same thing, you can get all the names doing something like this:

import * as Heroicons from '@heroicons/react/20/solid'
type Icons = keyof typeof Heroicons

And worst case you could just hard code a set of icon names into your project.

Hope that makes sense 👍

mattfelten commented 1 year ago

👍 Fair enough!

I'm not able to use the example you posted though, since I'm not using TS. And I'm not planning on hardcoding icon names, haha.