In most of the Icon components available in NPM you have to import the icon one by onee. this leads to a long list of imports if you heavily rely on the icons.

This component is a wrapper around the react-feather library, but the only difference from other components is that it imports the icons dynamically.

You need to import only the Icon component and not the icons themselves, you can specify the icons using the name prop.

The compoennt is devided in two parts: one contains the component definitions and the other one contains the icons.

The component composed if two files: the Icon.tsx (main component) and the icon_set.tsx (contains all the icons). If your set of icons is learge like in my case as I am using the feather icon, you can also use only the main component file and keep all the icons there if the set is small.

components/Icon.tsx
import React, { forwardRef } from 'react'
import { classes } from 'library'
import icon_sets from './icon_sets'
// type definitions
interface IconProps extends HTMLProps<HTMLElement> {
	name: IconNames
	size?: number
}

function Icon(props: T.IconProps) {
	const { tag: Tag = 'span', name, size = 18, ...attr } = props
	if (!(name in icon_sets)) return <></>

	attr.className = classes(props.className, 'inline-flex flex-center')
	attr.role = 'img'
	// prettier-ignore
	return (
		<Tag ref={refer} aria-hidden='true' {...attr}>
			<svg
				viewBox='0 0 24 24' width={size} height={size}
				fill='none' strokeWidth={2} stroke='currentcolor'
				strokeLinecap='round' strokeLinejoin='round'
			>
				{icon_sets[name]}
			</svg>
		</Tag>
	)
}

export default Icon
components/icon_set.tsx
const icons = {
	'avirup': <><path d="M13.35,10.92l-4.39,9.5c-0.6,1.29-1.89,2.12-3.31,2.12h0c-2.66,0-4.43-2.76-3.31-5.18L8.69,3.59 c1.31-2.83,5.32-2.83,6.63,0l6.36,13.76c1.12,2.42-0.65,5.18-3.31,5.18h-4.65" /><path d="M10.67,5.13" /></>,
	'activity': <><polyline points='22 12 18 12 15 21 9 3 6 12 2 12' /></ >,
	'airplay': <><path d='M5 17H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-1' /><polygon points='12 15 17 21 7 21 12 15' /> </>,
	'alert-circle': <><circle cx='12' cy='12' r='10' /> <line x1='12' y1='8' x2='12' y2='12' /> <line x1='12' y1='16' x2='12.01' y2='16' /> </>,
	...,
	'home': <><path d='M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z' /><polyline points='9 22 9 12 15 12 15 22' /> </>,
	'image': <><rect x='3' y='3' width='18' height='18' rx='2' ry='2' /> <circle cx='8.5' cy='8.5' r='1.5' /> <polyline points='21 15 16 10 5 21' /></ >,
}
export default icons

As you can see I am only using the inner html of the SVG file as icons. This icon_set is only a demo of how to use the component. Remember the SVG viewport hight and width, all the icons or paths are scaled to fit the viewport.

It is preffered to use icons with same sizes. My icons are sized 24x24 pixels os SVG viewBox='0 0 24 24'.

import Icon from '.components/Icon'
...
<Icon name='home' size={24} />