carloskiki / leptos-icons

An icon library for the leptos web framework
MIT License
84 stars 16 forks source link

Individual icon components prevent library usage #7

Closed lpotthast closed 1 year ago

lpotthast commented 1 year ago

Let's assume a component library provides a leptos component Foo, which may display an icon. The library may give the user the option to choose the specific icon to show.

But: How does Foo incorporate/display an "arbitrary" icon. And how should the user specify the icon to use?

One could imagine something like this, where Foo just takes some arbitrary View and includes that in its output:

<Foo icon=move || view! {cx <BsFolder />}/>

But the user might not even create an Icon here... Could also be a benefit (easy prarmeterization of the icon), but most likely not what a library author inteded. The library auther would also have no control over the icon in this case. The author can only accept an arbitrary nested view, as the user currently has no other means to specify an icon.

In this case, a selection of an icon by enum variant would be much more ergonomic and would allow any library authors to simply take an enum variant as a prop. (I followed this approach as well when doin some limited icon stuff in the Yew framework.)

<Foo icon=Icon::BsFolder/>

The problem lies in the fact that, right now, all icons are represented by individual leptos-components (functions) and no enum exists.

I think that an enum, defined as non_exhaustive, and with all it's variant feature-gated, is required for this library.

Two things are required:

I'm unsure on how to implement the second and welcome any suggestions! :)

A simple solution would be to generate a huge match statement inside the Icon component, where each arm is feature-gated and displays one icon by reusing the icon-components which are already getting generated, forwarding all possible arguments. The efficiency of such a match statement should be high. With the enum variants all having zero data, it should be a simple jump table at runtime.

carloskiki commented 1 year ago

This is a great idea!

The first method that came to my novice mind was to use a sort of runtime macro (I don't know if such a thing exists), to generate the icon declaration with the enum identifier. Your method seems way more stable though.

lpotthast commented 1 year ago

Thought about that too. One could write an icon! macro which would then simply contain the match. But if the component approach does not lead to a binary size increase or a runtime performance hit then we should probably prefer the component approach.

lpotthast commented 1 year ago

Can work on this tomorrow.

carloskiki commented 1 year ago

I will make a branch for this feature.