Skip to content
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

Make astro-icon usable from UI framework components #151

Open
PeterDraex opened this issue Nov 11, 2023 · 3 comments
Open

Make astro-icon usable from UI framework components #151

PeterDraex opened this issue Nov 11, 2023 · 3 comments

Comments

@PeterDraex
Copy link

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:

  1. 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"
  },
  1. Export framework-agnostic JSX component <Sprite>
    To do this, we would:
  • move the JSX code from Sprite.astro to Sprite.jsx (Sprite.astro would just receive props and pass it to Sprite.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?

@iivvaannxx
Copy link

iivvaannxx commented Nov 20, 2023

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.

@PeterDraex
Copy link
Author

@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.

@iivvaannxx
Copy link

iivvaannxx commented Nov 21, 2023

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants