The main idea is to only import react material UI icons when it is needed or rather when dynamically where we wouldn't know the icon name at compile time. (Let's gurentee that we would have valid icon names).
My approach was to use a require statment with dynamic path:
const IconComponent = require(`@material-ui/icons/${icon}`).default;
This works fine but some warnings are showing up.
./node_modules/@material-ui/icons/utils/createSvgIcon.d.ts 3:8 Module parse failed: Unexpected token (3:8) You may need an appropriate loader to handle this file type. | import SvgIcon from '@material-ui/core/SvgIcon'; | declare function createSvgIcon(path: React.ReactNode, displayName: string): typeof SvgIcon; | | export default createSvgIcon;
./node_modules/@material-ui/icons/index.d.ts 4:5 Module parse failed: Unexpected token (4:5) You may need an appropriate loader to handle this file type. | import SvgIcon from '@material-ui/core/SvgIcon'; |
type SvgIconComponent = typeof SvgIcon; | | export const AccessAlarm: SvgIconComponent;
My question is: How could we avoid these warnings and do the dynamic import in the appropriate way ?
You can create a hook for this. like the following.
//1) $ npm i string-similarity
import * as icons from '@material-ui/icons'
import stringSimilarity from 'string-similarity'
function useIcons(word) {
const iconsNames = Object.keys(icons)
var matches = stringSimilarity.findBestMatch(word, iconsNames)
const bestMathch = matches.bestMatch.target
const Icon = icons[bestMathch]
return Icon
}
export default useIcons
import Icon from './myCustomeHooks/useIcons'
// other file like
const Icon = useIcons('tablechart') // not the name should start with capital letter in case you use reactjs
// now you can use the icon as you like
<Icon/>
please note: import * as icons from '@material-ui/icons' is the same as const * as icons = require('@material-ui/icons').default;
import React from 'react';
import { loadCSS } from 'fg-loadcss';
import { makeStyles, createStyles, Theme } from '@material-ui/core/styles';
import { green } from '@material-ui/core/colors';
import Icon from '@material-ui/core/Icon';
const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
'& > .fa': {
margin: theme.spacing(2),
},
},
}),
);
export default function FontAwesome() {
const classes = useStyles();
React.useEffect(() => {
const node = loadCSS(
'https://use.fontawesome.com/releases/v5.12.0/css/all.css',
document.querySelector('#font-awesome-css'),
);
return () => {
node.parentNode!.removeChild(node);
};
}, []);
return (
<div className={classes.root}>
<Icon className="fa fa-plus-circle" />
<Icon className="fa fa-plus-circle" color="primary" />
<Icon className="fa fa-plus-circle" color="secondary" />
<Icon className="fa fa-plus-circle" style={{ color: green[500] }} />
<Icon className="fa fa-plus-circle" fontSize="small" />
<Icon className="fa fa-plus-circle" style={{ fontSize: 30 }} />
</div>
);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With