dioxus-community / dioxus-free-icons

Use free svg icons in your Dioxus projects easily with dioxus-free-icons.
Other
73 stars 18 forks source link

Newbie Question #35

Closed kurt-rhee closed 6 months ago

kurt-rhee commented 8 months ago

Hello,

I am totally new to frontend dev and I was wondering what is the type of a given icon? I would like to pass an icon as part of the inputs to a function.

pub fn render_sidebar (cx: Scope) -> Element {

    render! {
        div {
            class: "fixed top-0 left-0, h-screen w-16
            flex flex-col
            bg-primary text-slate-100 shadow-lg
            ",
            div {"A"}
            div {"B"}
            sidebar_icon(cx, IconProps!<FaSolarPanel>)
        }
    }
}

fn sidebar_icon (
    cx: Scope,
    icon: Icon,
) -> Element {
    render! {
        div {
            Icon {
                width: 30,
                height: 30,
                fill: "text-slate-400",
                icon: icon,
            }
        }
    }
}
marc2332 commented 8 months ago

Hey! You can add a generic that implements the IconShape, just like the built-in Icon component

kurt-rhee commented 8 months ago

Thank you @marc2332!

I maybe should have mentioned that I am pretty new to Rust as well. I tried a few different variation of the following code snippet, but had a hard time understanding the error messages.

pub struct IconGeneric<T: IconShape> {
    pub icon: T,
}

fn sidebar_icon<T>(
    cx: Scope,
    icon: IconGeneric<T>,
) -> Element {

Error message:

pub struct IconGeneric<T: IconShape> {
    pub icon: T,
}

fn sidebar_icon<T>(
    cx: Scope,
    icon: IconGeneric<T>,
) -> Element {
marc2332 commented 8 months ago

Thank you @marc2332!

I maybe should have mentioned that I am pretty new to Rust as well. I tried a few different variation of the following code snippet, but had a hard time understanding the error messages.

pub struct IconGeneric<T: IconShape> {
    pub icon: T,
}

fn sidebar_icon<T>(
    cx: Scope,
    icon: IconGeneric<T>,
) -> Element {

Error message:

pub struct IconGeneric<T: IconShape> {
    pub icon: T,
}

fn sidebar_icon<T>(
    cx: Scope,
    icon: IconGeneric<T>,
) -> Element {

Heh, Looks like you pasted the code again instead of the error. It's okay

Try something like this :eyes: :

pub fn SideBar(cx: Scope) -> Element {
    render! {
        div {
            class: "fixed top-0 left-0, h-screen w-16
            flex flex-col
            bg-primary text-slate-100 shadow-lg
            ",
            div {"A"}
            div {"B"}
            SideBarIcon { 
                icon: FaSolarPanel
            }
        }
    }
}

#[inline_props]
fn SideBarIcon<T: IconShape>(
    cx: Scope,
    icon: T,
) -> Element {
  render! {
        div {
            Icon {
                width: 30,
                height: 30,
                fill: "text-slate-400",
                icon: icon
            }
        }
    }
}
marc2332 commented 8 months ago

I just noticed that you were embedding components like sidebar_icon(cx, IconProps!<FaSolarPanel>) but that's not the right way, You have to do it like this:

SideBarIcon { 
       icon: FaSolarPanel
}
kurt-rhee commented 8 months ago

Woops! I tried copying your example above and am getting the following errors. (Thank you a million for still helping me through this by the way)

            SideBarIcon { 
                icon: FaSolarPanel
            }
        }
    }
}

#[inline_props]
fn SideBarIcon<T: IconShape>(
    cx: Scope,
    icon: T,
) -> Element {
  render! {
        div {
            Icon {
                width: 30,
                height: 30,
                fill: "text-slate-400",
                icon: icon
            }
        }
    }
}
error[E0277]: the trait bound `&T: IconShape` is not satisfied
  --> src/pages/sidebar.rs:27:3
   |
27 | /   render! {
28 | |         div {
29 | |             Icon {
30 | |                 width: 30,
31 | |                 height: 30,
32 | |                 fill: "text-slate-400",
   | |                 ---- required by a bound introduced by this call
...  |
35 | |         }
36 | |     }
   | |_____^ the trait `IconShape` is not implemented for `&T`
   |
   = help: the following other types implement trait `IconShape`:
             FaCommentDots
             FaPassport
             FaSocks
             FaUnderline
             FaFileArrowUp
             FaHeadphonesSimple
             FaCloudMeatball
             FaCaretDown
           and 1379 others
note: required by a bound in `dioxus_free_icons::icon_component::IconPropsBuilder::<'a, (__icon, __height, __width, (), __class, __title), T>::fill`
  --> /home/skrhee/.cargo/registry/src/index.crates.io-6f17d22bba15001f/dioxus-free-icons-0.7.0/src/icon_component.rs:12:29
   |
12 | pub struct IconProps<'a, T: IconShape> {
   |                             ^^^^^^^^^ required by this bound in `IconPropsBuilder::<'a, (__icon, __height, __width, (), __class, __title), T>::fill`
...
23 |     pub fill: &'a str,
   |         ---- required by a bound in this associated function
marc2332 commented 8 months ago

Woops! I tried copying your example above and am getting the following errors. (Thank you a million for still helping me through this by the way)

            SideBarIcon { 
                icon: FaSolarPanel
            }
        }
    }
}

#[inline_props]
fn SideBarIcon<T: IconShape>(
    cx: Scope,
    icon: T,
) -> Element {
  render! {
        div {
            Icon {
                width: 30,
                height: 30,
                fill: "text-slate-400",
                icon: icon
            }
        }
    }
}
error[E0277]: the trait bound `&T: IconShape` is not satisfied
  --> src/pages/sidebar.rs:27:3
   |
27 | /   render! {
28 | |         div {
29 | |             Icon {
30 | |                 width: 30,
31 | |                 height: 30,
32 | |                 fill: "text-slate-400",
   | |                 ---- required by a bound introduced by this call
...  |
35 | |         }
36 | |     }
   | |_____^ the trait `IconShape` is not implemented for `&T`
   |
   = help: the following other types implement trait `IconShape`:
             FaCommentDots
             FaPassport
             FaSocks
             FaUnderline
             FaFileArrowUp
             FaHeadphonesSimple
             FaCloudMeatball
             FaCaretDown
           and 1379 others
note: required by a bound in `dioxus_free_icons::icon_component::IconPropsBuilder::<'a, (__icon, __height, __width, (), __class, __title), T>::fill`
  --> /home/skrhee/.cargo/registry/src/index.crates.io-6f17d22bba15001f/dioxus-free-icons-0.7.0/src/icon_component.rs:12:29
   |
12 | pub struct IconProps<'a, T: IconShape> {
   |                             ^^^^^^^^^ required by this bound in `IconPropsBuilder::<'a, (__icon, __height, __width, (), __class, __title), T>::fill`
...
23 |     pub fill: &'a str,
   |         ---- required by a bound in this associated function

No problem! Try this:

pub fn SideBar(cx: Scope) -> Element {
    render! {
        div {
            class: "fixed top-0 left-0, h-screen w-16
            flex flex-col
            bg-primary text-slate-100 shadow-lg
            ",
            div {"A"}
            div {"B"}
            SideBarIcon { 
                icon: FaSolarPanel
            }
        }
    }
}

#[inline_props]
fn SideBarIcon<T: IconShape + Clone>(
    cx: Scope,
    icon: T,
) -> Element {
  render! {
        div {
            Icon {
                width: 30,
                height: 30,
                fill: "text-slate-400",
                icon: icon.clone()
            }
        }
    }
}