diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..512dd73 --- /dev/null +++ b/.babelrc @@ -0,0 +1,4 @@ +{ + "presets": ["next/babel"], + "plugins": ["babel-plugin-macros"] +} \ No newline at end of file diff --git a/src/utils/getIcons.ts b/src/utils/getIcons.ts new file mode 100644 index 0000000..e9a70df --- /dev/null +++ b/src/utils/getIcons.ts @@ -0,0 +1,28 @@ +import codegen from "babel-plugin-codegen/macro"; + +/* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call */ +// language=JavaScript +const fn = codegen` + const {IconsManifest} = require("react-icons/lib/cjs"); + let codes = "(function (id) { switch (id) {"; + IconsManifest.forEach(({id}) => { + codes += 'case "' + id + '":\\n return import(/* webpackChunkName: "' + id + '" */ "react-icons/' + id + '/index");\\n' + }) + codes += '}})'; + module.exports = codes; // module.exports = "import('react-icons/fa/index')" +`; +/* eslint-enable */ + +export function getIcons(id: string) { + /* + Dynamic Import with improved performance. + Macros are used to avoid bundling unnecessary modules. + Similar to this code + ``` + return import(`react-icons/${iconsId}/index`); + ``` + */ + + // eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-return + return fn(id); +} \ No newline at end of file diff --git a/src/utils/iconList.ts b/src/utils/iconList.ts new file mode 100644 index 0000000..9ea18e5 --- /dev/null +++ b/src/utils/iconList.ts @@ -0,0 +1,10 @@ +// @ts-nocheck +// @codegen +/* eslint-disable */ + +// @ts-ignore +module.exports = require("./icons").ICON_SET_IDS + .map(setId => Object.keys(require(`react-icons/${setId}/index`)).map(id => ( + {id, setId} + ))) + .flat() \ No newline at end of file diff --git a/src/utils/icons.ts b/src/utils/icons.ts new file mode 100644 index 0000000..423fa88 --- /dev/null +++ b/src/utils/icons.ts @@ -0,0 +1,14 @@ +import * as ReactIconsLib from "react-icons/lib"; +import type {IconManifest} from "react-icons"; + +// @ts-ignore TS7053 ;; This reaches into React Icon's internals so it really cannot be made typesafe for our purposes. +export const ALL_ICON_SETS: IconManifest[] = ReactIconsLib["IconsManifest"] as IconManifest[]; + +// An object referencing each of the icon sets, keyed by its 'id' (two/three letter identifier). +export const ALL_ICON_SETS_BY_ID: Record = Object.fromEntries(ALL_ICON_SETS.map(set => [set.id, set])); + +// A list of all the icon sets. +export const ICON_SET_IDS: string[] = Object.keys(ALL_ICON_SETS_BY_ID); + +// A getter for code splitting loaders. +export const getIconById = (id: string): IconManifest | undefined => ALL_ICON_SETS_BY_ID[id]; \ No newline at end of file