other-emerald•15mo ago
How to make resource icons more flexible?
Hi there, I'm creating something like a CRM using Refine with Next.js and a Headless UI framework (I'm using Shadcn), so, I already have my resource items like this:
The main idea here is to have a
Menu component and a Header (this one will contain a mobile version of the menu) component in both I use the useMenu hook to get the menu items but in each component I need to use different classNames for the icons.
So the question is, how can I make the icon in the resource item accepts a function that returns a ReactNode (which is the expected type for the icon). I tried to create my custom type as follows:
But I get a TypeScript error and it's driving me crazy, so could anyone help me pls?5 Replies
Hi @SpiritHeiBai. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
To make the
icon in the resource item more flexible and accept a function that returns a ReactNode, you can extend the IResourceItem interface to include a custom type for the icon property. This custom type can be a function that takes a className parameter and returns a ReactNode, or it can be a ReactNode directly.
Here's how you can achieve this:
1. Extend the IResourceItem Interface:
Define a new interface that extends IResourceItem and modifies the icon property in the meta object to accept either a ReactNode or a function that returns a ReactNode.
2. Update Your Resource Items:
Use this new interface for your resource items and provide the icon property as a function where needed.
Here is the updated code:
3. Use the icon Property in Your Components:
When rendering the icons in your Menu and Header components, you can call the function with the desired className.
Here is an example of how you might use it in a Menu component:
By following these steps, you can make the icon property in your resource items more flexible and allow it to accept a function that returns a ReactNode with custom classNames.
For more details, you can refer to the Refine documentation (https://refine.dev/docs/core/refine-component/#icon) and the useResource hook documentation (https://refine.dev/docs/routing/hooks/use-resource/#return-value).
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@892137297519181935> kapa.ai is still learning and improving, please let us know how it did by reacting below
realistic-cyan•15mo ago
Hello @SpiritHeiBai, unfortunately
resource.meta.icon not designed to works as function thats why type is ReactNode .
you can see following links how we use icon:
breadcrumb: https://github.com/refinedev/refine/blob/master/packages/antd/src/components/breadcrumb/index.tsx#L56C15-L56C29
sider: https://github.com/refinedev/refine/blob/master/packages/antd/src/components/themedLayoutV2/sider/index.tsx#L105
But it's a great idea. I will talk with the core team to implement something like this.
but while we're waiting for this feature, you can make these improvements:
just can add customIcon field to meta and you can make your implementation of <Sider>
other-emeraldOP•15mo ago
Thanks so much @Alican Erdurmaz I do really appreciate it. Unfortunately, I already did that as well and I get the following error, is there anything I need to change/update to make it work?

other-emeraldOP•15mo ago
Ok, just for the record, I think I found a way to do it. Maybe it's not the cleanest way to achieve it but it works. So here is my solution and hopefully works for some else.
I had to create a wrapper function that actually accepts the
icon and some additional props to pass to it and returns a new element with those props, so here's the function:
At this point idk exactly the performance issues that might cause this, but still work, if there is a better way to do it or there's an improvement you want to make to the code, you're more than welcome to add it and share it 🙂 So, to use it I think is pretty clear but if not here is an example: