Files
beau-gosse-du-92/src/ui/components/icons.rs
Adrien a8a7b16e9f
All checks were successful
ci/woodpecker/pr/validate Pipeline was successful
👷 Add cargo sort-derives tool
2025-04-27 22:10:27 +02:00

181 lines
5.6 KiB
Rust

use const_format::formatcp;
use dioxus::prelude::*;
use dioxus_free_icons::icons::fa_solid_icons::{
FaComments, FaLayerGroup, FaMagnifyingGlass, FaPeopleGroup,
};
use dioxus_free_icons::{Icon, IconShape};
turf::style_sheet!("src/ui/components/icons.scss");
include!(concat!(env!("OUT_DIR"), "/style_tokens.rs"));
use style::{COLOR_PRIMARY_100, COLOR_TERNARY_100};
macro_rules! transparent_icon {
($name:ident, $icon:ident) => {
pub fn $name() -> Element {
rsx! {
style { {STYLE_SHEET} }
Icon {
class: ClassName::TRANSPARENT_ICON,
icon: $icon,
}
}
}
};
}
transparent_icon!(SearchIcon, FaMagnifyingGlass);
transparent_icon!(SpacesIcon, FaLayerGroup);
transparent_icon!(ChatsIcon, FaComments);
transparent_icon!(RoomsIcon, FaPeopleGroup);
#[derive(Clone, PartialEq)]
pub(crate) struct LogoShape;
impl IconShape for LogoShape {
fn view_box(&self) -> &str {
"0 0 184 94"
}
fn xmlns(&self) -> &str {
"http://www.w3.org/2000/svg"
}
fn child_elements(&self) -> Element {
rsx! {
path {
"stroke-linejoin": "round",
"stroke-width": "6",
d: "M121.208 2 2 57.011l70.927-.265L61.363 92 182 36.724h-69.498L121.208 2Z"
}
}
}
}
pub fn LogoIcon() -> Element {
rsx! {
style { {STYLE_SHEET} }
Icon {
icon: LogoShape,
}
}
}
const _PYRAMID_OFFSET_X: f64 = 1.0;
const _PYRAMID_OFFSET_Y: f64 = 2.0;
const _PYRAMID_STROKE_WIDTH: f64 = 2.0;
const _PYRAMID_DIST_FROM_CENTRAL_X: f64 = 65.0;
const _PYRAMID_DIST_FROM_CENTRAL_E1_Y: f64 = 83.0;
const _PYRAMID_EDGES_E1_X: f64 = _PYRAMID_DIST_FROM_CENTRAL_X + _PYRAMID_OFFSET_X;
const _PYRAMID_EDGES_E1_Y: f64 = _PYRAMID_OFFSET_Y;
const _PYRAMID_LEFT_EDGE_E2_X: f64 = _PYRAMID_OFFSET_X;
const _PYRAMID_LEFT_EDGE_E2_Y: f64 = _PYRAMID_DIST_FROM_CENTRAL_E1_Y + _PYRAMID_OFFSET_Y;
const _PYRAMID_CENTRAL_EDGE_E2_X: f64 = _PYRAMID_DIST_FROM_CENTRAL_X + _PYRAMID_OFFSET_X;
const _PYRAMID_CENTRAL_EDGE_E2_Y: f64 = 100.0 + _PYRAMID_OFFSET_Y;
const _PYRAMID_CENTRAL_EDGE_Y_LEN: f64 = _PYRAMID_CENTRAL_EDGE_E2_Y - _PYRAMID_EDGES_E1_Y;
const _PYRAMID_RIGHT_EDGE_E2_X: f64 = 130.0 + _PYRAMID_OFFSET_X;
const _PYRAMID_RIGHT_EDGE_E2_Y: f64 = _PYRAMID_LEFT_EDGE_E2_Y;
// _PYRAMID_VIEWBOX_HEIGHT and _PYRAMID_VIEWBOX_WIDTH are casted as i64 to be able to render
// viwebox string statically (formatcp doesn't support f64 type)
const _PYRAMID_VIEWBOX_HEIGHT: i64 = (_PYRAMID_CENTRAL_EDGE_E2_Y + _PYRAMID_STROKE_WIDTH) as i64;
const _PYRAMID_VIEWBOX_WIDTH: i64 = (_PYRAMID_RIGHT_EDGE_E2_X + _PYRAMID_STROKE_WIDTH) as i64;
const _PYRAMID_VIEWBOX: &str = formatcp!("0 0 {_PYRAMID_VIEWBOX_WIDTH} {_PYRAMID_VIEWBOX_HEIGHT}");
#[derive(Clone, PartialEq)]
struct PyramidShape {
color: String,
ratio: f64,
progress_color: String,
}
impl IconShape for PyramidShape {
fn view_box(&self) -> &str {
_PYRAMID_VIEWBOX
}
fn xmlns(&self) -> &str {
"http://www.w3.org/2000/svg"
}
fn child_elements(&self) -> Element {
let inverted_ratio = 1.0 - self.ratio;
let central_edge_ratio_e2_y =
_PYRAMID_CENTRAL_EDGE_Y_LEN * inverted_ratio + _PYRAMID_OFFSET_Y;
let left_edge_ratio_e1_x = _PYRAMID_OFFSET_X + (_PYRAMID_DIST_FROM_CENTRAL_X * self.ratio);
let right_edge_ratio_e1_x = _PYRAMID_OFFSET_X
+ _PYRAMID_EDGES_E1_X
+ (_PYRAMID_DIST_FROM_CENTRAL_X * inverted_ratio);
let no_central_edge_ratio_e1_y =
_PYRAMID_OFFSET_Y + (_PYRAMID_DIST_FROM_CENTRAL_E1_Y * inverted_ratio);
rsx! {
g {
stroke: "#fff",
"stroke-linejoin": "round",
"stroke-width": _PYRAMID_STROKE_WIDTH,
fill: "#{self.progress_color}",
path {
fill: "#{self.color}",
d: "\
M {_PYRAMID_EDGES_E1_X} {_PYRAMID_EDGES_E1_Y} \
L {_PYRAMID_RIGHT_EDGE_E2_X} {_PYRAMID_RIGHT_EDGE_E2_Y} \
L {_PYRAMID_EDGES_E1_X} {_PYRAMID_CENTRAL_EDGE_E2_Y} \
M {_PYRAMID_EDGES_E1_X} {_PYRAMID_EDGES_E1_Y} \
L {_PYRAMID_LEFT_EDGE_E2_X} {_PYRAMID_LEFT_EDGE_E2_Y} \
L {_PYRAMID_EDGES_E1_X} {_PYRAMID_CENTRAL_EDGE_E2_Y} \
M {_PYRAMID_EDGES_E1_X} {_PYRAMID_EDGES_E1_Y} \
V {_PYRAMID_CENTRAL_EDGE_Y_LEN}",
}
path {
d: "\
M {_PYRAMID_CENTRAL_EDGE_E2_X} {_PYRAMID_CENTRAL_EDGE_E2_Y} \
V {central_edge_ratio_e2_y} \
L {left_edge_ratio_e1_x} {no_central_edge_ratio_e1_y} \
L {_PYRAMID_LEFT_EDGE_E2_X} {_PYRAMID_LEFT_EDGE_E2_Y} Z",
}
path {
d: "\
M {_PYRAMID_CENTRAL_EDGE_E2_X} {_PYRAMID_CENTRAL_EDGE_E2_Y} \
V {central_edge_ratio_e2_y} \
L {right_edge_ratio_e1_x} {no_central_edge_ratio_e1_y} \
L {_PYRAMID_RIGHT_EDGE_E2_X} {_PYRAMID_RIGHT_EDGE_E2_Y} Z",
}
}
}
}
}
#[derive(Clone, PartialEq, Props)]
pub struct PyramidProps {
color: Option<String>,
#[props(default = 0.5)]
ratio: f64,
progress_color: Option<String>,
}
pub fn Pyramid(props: PyramidProps) -> Element {
let color = props.color.unwrap_or(COLOR_PRIMARY_100.to_string());
let progress_color = props
.progress_color
.unwrap_or(COLOR_TERNARY_100.to_string());
rsx! {
style { {STYLE_SHEET} }
Icon {
class: ClassName::PYRAMID_ICON,
icon: PyramidShape { ratio: props.ratio, color, progress_color },
}
}
}