fc_dioxus/components/
icon.rs1use crate::{
6 core::{
7 assets,
8 icons::{ICON_STROKE_WIDTH, ICON_VIEWBOX},
9 },
10 prelude::*,
11 theme::use_stylesheets,
12};
13
14const BEM: Bem = Bem::new("fc-icon");
15fc_modifier! {
16 pub enum IconSize for BEM {
18 Md => None,
20 Sm => "sm",
22 Lg => "lg",
24 }
25}
26fc_modifier! { enum IconDirection for BEM { Fixed => None, Mirror => "mirror" } }
27
28#[component]
36pub fn Icon(
37 name: IconName,
38 #[props(default)] size: IconSize,
39 #[props(default)]
41 label: Option<AccessibleName>,
42 #[props(default)] class: Option<String>,
43) -> Element {
44 let classes = ClassList::new(BEM.block())
45 .with_modifier(BEM, size)
46 .with_modifier(
47 BEM,
48 if name.mirrored() {
49 IconDirection::Mirror
50 } else {
51 IconDirection::Fixed
52 },
53 )
54 .extend(class.as_deref())
55 .to_string();
56 let labelled = label.is_some();
57 rsx! {
58 if use_stylesheets() { document::Stylesheet { href: assets::COMPONENTS_ICON_CSS } }
59 svg { class: classes, view_box: ICON_VIEWBOX, fill: "none", stroke: "currentColor",
62 stroke_width: ICON_STROKE_WIDTH, stroke_linecap: "round", stroke_linejoin: "round",
63 role: labelled.then_some("img"),
64 "aria-label": label.map(|label| label.to_string()),
65 "aria-hidden": (!labelled).then_some("true"),
66 "focusable": (!labelled).then_some("false"),
67 path { d: name.path() }
68 }
69 }
70}
71
72#[component]
78pub fn IconButton(
79 icon: IconName,
80 label: AccessibleName,
81 #[props(default)] variant: ButtonVariant,
82 #[props(default)] size: ButtonSize,
83 #[props(default)] availability: Availability,
84 #[props(default)]
86 busy: bool,
87 #[props(default)] pressed: Option<bool>,
88 #[props(default)] r#type: ButtonType,
89 #[props(default)] onclick: Option<EventHandler<MouseEvent>>,
90 #[props(default)] class: Option<String>,
91 #[props(extends = GlobalAttributes, extends = button)] attributes: Vec<Attribute>,
92) -> Element {
93 let props = ButtonProps {
95 variant,
96 size,
97 block: false,
98 availability,
99 busy,
100 pressed,
101 r#type,
102 icon_label: Some(label),
103 onclick,
104 class,
105 attributes,
106 children: rsx! { if !busy { Icon { name: icon } } },
107 };
108 rsx! { Button { ..props } }
109}