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
foreign-sapphire•2w 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>
xenial-black•2w 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?
xenial-black•7d 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: