-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathlib.rs
219 lines (208 loc) · 6.95 KB
/
lib.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
#![allow(non_snake_case)]
#![warn(missing_docs)]
//! # 🧬 Dioxus Material Icons
//!
//! This project provides a simple but configurable component to render Google's Material Icons in Dioxus.
//!
//! ## 🚀 How to get started
//!
//! `cargo add dioxus-material-icons`
//!
//! This project introduces two components:
//!
//! 1. [`MaterialIconStylesheet`](MaterialIconStylesheet)
//! 2. [`MaterialIcon`](MaterialIcon)
//!
//! To be able to use the [`MaterialIcon`](MaterialIcon) component anywhere in your code, you first have to include
//! a [`MaterialIconStylesheet`](MaterialIconStylesheet) component. When you want to use the default settings,
//! just add it to your app's root component like this:
//!
//! ```no_rust
//! MaterialIconStylesheet { }
//! ```
//!
//! Have a look at the [`MaterialIconStylesheet`](MaterialIconStylesheet) docs for more options like self-hosting the icon font file.
//!
//! After that you can use the `MaterialIcon` component like you would expect it:
//!
//! ```no_rust
//! MaterialIcon { name: "settings" }
//! ```
//!
//! You can additionally specify the color and size.
//!
//! ```no_rust
//! MaterialIcon {
//! name: "settings",
//! size: 24,
//! color: MaterialIconColor::Light,
//! }
//! ```
//!
//! ## 💡 Examples
//!
//! - [Button Example](https://github.com/lennartkloock/dioxus-material-icons/blob/main/examples/button.rs)
//!
//! ## 🔗 Useful links
//!
//! - [Overview of all icons](https://fonts.google.com/icons?selected=Material+Icons) (including names)
//!
//! ### Alternatives
//!
//! - [dioxus-free-icons](https://crates.io/crates/dioxus-free-icons) (Support for other icon packs)
//!
//! ## 📜 License
//!
//! This software is licensed under the terms of the MIT License.
//!
//! Note: All Material Icons are licensed under the Apache License 2.0.
//!
//! © 2023 Lennart Kloock
use dioxus::prelude::*;
/// Props for the [`MaterialIconStylesheet`](MaterialIconStylesheet) component
#[derive(Props, PartialEq, Clone)]
pub struct MaterialIconStylesheetProps {
/// Variant prop for the [`MaterialIconStylesheet`](MaterialIconStylesheet) component
///
/// See [`MaterialIconVariant`](MaterialIconVariant) for more information.
#[props(default = MaterialIconVariant::Regular)]
pub variant: MaterialIconVariant,
}
/// Variants (also called categories) of the Material Icon font
///
/// See all variants [here](https://fonts.google.com/icons?selected=Material+Icons).
#[derive(PartialEq, Clone)]
pub enum MaterialIconVariant {
/// Regular
///
/// Also called Filled.
Regular,
/// Outlined
Outlined,
/// Round
Round,
/// Sharp
Sharp,
/// Two tone
TwoTone,
/// Self hosted font file
///
/// Provide an url to a ttf or otf file.
/// You can download the files [here](https://github.com/google/material-design-icons/tree/master/font).
SelfHosted(String),
}
/// Stylesheet component
///
/// This component includes the Material Icon stylesheet.
/// This is required to render all Material Icons correctly.
///
/// You can provide a variant as a prop (e.g. Round).
/// When you want to provide your own self-hosted font file,
/// please use [`MaterialIconVariant::SelfHosted`](MaterialIconVariant::SelfHosted) and pass the
/// file path or url to your .ttf or .otf file to it.
/// See the [button example](https://github.com/lennartkloock/dioxus-material-icons/blob/main/examples/button.rs).
pub fn MaterialIconStylesheet(props: MaterialIconStylesheetProps) -> Element {
let href = match &props.variant {
MaterialIconVariant::SelfHosted(file) => {
return rsx!(
style { {format!(include_str!("./self-hosted-styles.css"), file)} }
);
}
MaterialIconVariant::Regular => "https://fonts.googleapis.com/icon?family=Material+Icons",
MaterialIconVariant::Outlined => {
"https://fonts.googleapis.com/icon?family=Material+Icons+Outlined"
}
MaterialIconVariant::Round => {
"https://fonts.googleapis.com/icon?family=Material+Icons+Round"
}
MaterialIconVariant::Sharp => {
"https://fonts.googleapis.com/icon?family=Material+Icons+Sharp"
}
MaterialIconVariant::TwoTone => {
"https://fonts.googleapis.com/icon?family=Material+Icons+Two+Tone"
}
};
rsx!(document::Link {
href: "{href}",
rel: "stylesheet"
})
}
/// Props for the [`MaterialIcon`](MaterialIcon) component
#[derive(Props, PartialEq, Clone)]
pub struct MaterialIconProps {
/// Name (e.g. `home`)
///
/// Browse all icons [here](https://fonts.google.com/icons?selected=Material+Icons).
#[props(into)]
pub name: String,
/// Size in pixels
///
/// Optional
pub size: Option<u32>,
/// Color
///
/// Optional
#[props(into)]
pub color: Option<MaterialIconColor>,
}
/// Colors of Material Icons
///
/// As described [here](https://developers.google.com/fonts/docs/material_icons#styling_icons_in_material_design).
#[derive(PartialEq, Clone)]
pub enum MaterialIconColor {
/// For using icons as black on a light background.
Dark,
/// For using icons as black on a light background.
DarkInactive,
/// For using icons as white on a dark background.
Light,
/// For using icons as white on a dark background.
LightInactive,
/// Custom color, any valid CSS color
///
/// E.g.: `#0000ff` or `red`
Custom(String),
}
impl<T: Into<String>> From<T> for MaterialIconColor {
fn from(value: T) -> Self {
Self::Custom(value.into())
}
}
impl MaterialIconColor {
/// Converts the color to its corresponding CSS color
pub fn to_css_color(&self) -> &str {
match self {
MaterialIconColor::Dark => "rgba(0, 0, 0, 0.54)",
MaterialIconColor::DarkInactive => "rgba(0, 0, 0, 0.26)",
MaterialIconColor::Light => "rgba(255, 255, 255, 1)",
MaterialIconColor::LightInactive => "rgba(255, 255, 255, 0.3)",
MaterialIconColor::Custom(c) => c,
}
}
}
/// Create a new `MaterialIconColor::Custom` variant
pub fn IconColor<T: Into<String>>(color: T) -> MaterialIconColor {
MaterialIconColor::Custom(color.into())
}
/// Material Icon component
///
/// This component can be used to render a Material Icon.
pub fn MaterialIcon(props: MaterialIconProps) -> Element {
// The `font-size` attribute has to be explicitly declared as `inherit` because the stylesheet sets a default of 24px
let css_size = props
.size
.map(|s| format!("{s}px"))
.unwrap_or_else(|| "inherit".to_string());
let css_color = props
.color
.as_ref()
.map(|c| format!("color: {};", c.to_css_color()))
.unwrap_or_default();
rsx!(
span {
class: "material-icons material-icons-outlined material-icons-round material-icons-sharp material-icons-two-tone md-48",
style: "font-size: {css_size}; {css_color} user-select: none;",
{props.name}
}
)
}