-
-
Notifications
You must be signed in to change notification settings - Fork 911
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
Get Icon dynamically #998
Comments
You can render an svg element pointing to type Props = {
icon: string;
color?: string;
size?: number;
};
export function Icon({ icon, color = "inherit", size = 18 }: Props) {
return (
<svg
style={{
stroke: "currentColor",
strokeWidth: 1.75,
strokeLinecap: "round",
strokeLinejoin: "round",
fill: "none",
color: color,
width: `${size}px`,
height: `${size}px`
}}
>
<use href={"path/to/node_modules/@tabler/icons/tabler-sprite-nostroke.svg#tabler-" icon} />
</svg>
);
} This is how I was doing it at first but I had issues with Electron loading in the entire sprite sheet for each icon in production mode (worked fine in dev mode), so I also have the Tabler Icons Webfont package and use this instead: import "@tabler/icons-webfont/tabler-icons.min.css";
type Props = {
icon: string;
color?: string;
size?: number;
};
export function Icon({ icon, color = "inherit", size = 18 }: Props) {
return (
<i
className={`ti ti-${icon}`}
style={{
fontSize: `${size}px`,
color: color
}}
/>
);
} |
Have you tried rendering a list of all these icons? |
I support the addition of this capability 👍 I'm currently working on a component that requires the ability to accept an icon name as a prop and dynamically render it inside. Having this feature would greatly enhance the flexibility of the component. Additionally, it would be beneficial to have an enum or type that provides a comprehensive list of all available icons. This way, developers can easily reference and choose from a standardized set of icons when using the component. |
Here is my attempt: (Optional: get a list of all available icons) import { icons } from "@tabler/icons-react";
import { useState } from "react";
import dynamic from "next/dynamic";
export default function Home() {
const [icon, setIcon] = useState<string>("IconAbc");
return (
<main className={`flex min-h-screen flex-col items-center p-24 gap-4`}>
<DynamicIcon icon={icon} />
{icon}
<div className="grid grid-cols-12 h-96 overflow-scroll">
{Object.entries(icons).map(([key, Value]) => (
<button
className="p-1 hover:bg-red-500"
key={key}
onClick={() => setIcon(key)}
title={key}
>
<Value />
</button>
))}
</div>
</main>
);
}
const DynamicIcon = ({ icon }: { icon?: string }) => {
if (!icon) return null;
const Icon = dynamic(
() => import(`@tabler/icons-react/dist/esm/icons/${icon}.mjs`),
{
loading: () => <p>Loading...</p>,
}
);
return <Icon />;
}; |
@tsnery This is because you are importing the entire namespace. Your app may feel faster, but you download every icon in the first-load |
Hey guys! Thank you for this update, it was just in time when I started integrating this into my project. I may be confusing something, but I couldn't get it to work when running a development environment. When I import Is this a correct way to do this? 'use client';
import {
IconFileUnknown,
IconLoader2,
dynamicImports,
} from '@tabler/icons-react';
import dynamic from 'next/dynamic';
const LoadingIcon = () => (
<IconLoader2 className="animate-pulse" aria-label="Icon is loading..." />
);
type TIconType = keyof typeof dynamicImports.default;
export const getDynamicIcon = (icon: TIconType) => {
const Icon = dynamic(
async () => {
try {
const componentImport = await dynamicImports.default[icon]();
if (!componentImport) {
return IconFileUnknown;
}
return componentImport.default;
} catch (error) {
return IconFileUnknown;
}
},
{
loading: LoadingIcon,
}
);
return Icon;
}; UpdateI figured this out when I looked closer into @timheerwagen's solution, what a dumb mistake 🤦♂️ const importsMap = (await import('@tabler/icons-react')).dynamicImports.default;
return importsMap[icon as keyof typeof importsMap]().catch(
() => IconFileUnknown
); Also if you want to add global Typescript icon type support to your IDE, add this to your root import { dynamicImports } from '@tabler/icons-react';
declare global {
declare type TIconType = keyof typeof dynamicImports.default;
} |
is there way to render all the icons instead of mentioning names every time, i wanted to list all icons in my app? |
Is there a way to import the Icon dynamically in React? For example:
The text was updated successfully, but these errors were encountered: