astro-icon
astro-icon copied to clipboard
Make `astro-icon` usable from UI framework components
Currently, it is not possible to call Astro components from UI frameworks, so it is currently not possible to use astro-icon
on interactive websites. The issue is that astro-icon
only exports Astro components, which cannot be used from within UI frameworks.
I see two approaches to fix this:
- Let developers create their own
<Sprite>
component in their app.
This is currently not possible, because the package exports are limited to:
"exports": {
".": "./index.ts",
"./pack": "./lib/createIconPack.ts"
},
Which would need to be changed to:
"exports": {
".": "./index.ts",
"./pack": "./lib/createIconPack.ts"
"./context": "./lib/context.ts",
"./constants": "./lib/constants.ts"
},
- Export framework-agnostic JSX component
<Sprite>
To do this, we would:
- move the JSX code from
Sprite.astro
toSprite.jsx
(Sprite.astro
would just receive props and pass it toSprite.jsx
) - export both JSX and Astro component However, I guess this would not work for non-JSX UI frameworks (e.g. Svelte).
What do you think? Would a PR for either of these solutions be accepted?
Correct me if I'm mistaken, but I believe you can actually do that already, Astro allows the usage of Astro components in UI framework components through named slots.
The example in the docs uses a <MyReactComponent>
as an example and a <MyAstroComponent slot='name'>
. In your case would be exactly the same, just using <Icon>
instead of <MyAstroComponent>
. Example:
<MyReactComponentOrWhateverFramework>
<Icon name='mdi:home' slot='icon' />
</MyReactComponentOrWhateverFramework>
Just ensure you have a slot inside your component named icon
. In React you don't do this through slots though, you need to have a prop named the same you are giving to the slot
attribute. See this for an example. For other frameworks like Svelte or Vue I think this works seamlessly.
@iivvaannxx I think that would work, but turn out to be very impractical for an interactive website. Since Astro components can't be included from framework components, all re-usable components tend to be framework components. Only the root level pages are Astro components. That means that all <Icon />
s must be loaded on the root page level and passed down the component hierarchy through slots, sometimes going 5 levels deep to reach the place where the icon should be displayed. It hurts readability too much.
@PeterDraex Yeah, in that situation it's true that is a bit of a pain to do so. Then I guess that this library may not be your best option for your use case. You could take a look at unplugin-icons
. It's very easy to use and it's framework agnostic out of the box. It uses the same sets of icons that astro-icon
uses (from Iconify).
You lose indeed many of the features that this library offers for Astro icons but if you're using it only for icons then unplugin-icons
is your best next option. If you pretend to use the icons on many different frameworks I recommend checking this issue.
Also, it seems this library is receiving less and less updates so if you have any ideas, I would recommend going to this proposal which talks about Astro native Icon support.