rustyle_css/components/
alert.rs1use super::{ComponentStyle, Size, Variant};
6use crate::css::{Color, Radius, Spacing};
7use crate::tokens::{BorderTokens, ColorTokens, SpacingTokens};
8
9#[derive(Clone, Debug)]
11pub struct AlertStyle {
12 pub variant: Variant,
13 pub size: Size,
14 pub tokens: Option<AlertTokens>,
15}
16
17#[derive(Clone, Debug)]
19pub struct AlertTokens {
20 pub colors: ColorTokens,
21 pub spacing: SpacingTokens,
22 pub borders: BorderTokens,
23}
24
25impl AlertStyle {
26 pub fn new(variant: Variant, size: Size) -> Self {
28 Self {
29 variant,
30 size,
31 tokens: None,
32 }
33 }
34
35 pub fn tokens(mut self, tokens: AlertTokens) -> Self {
37 self.tokens = Some(tokens);
38 self
39 }
40
41 fn background_color(&self) -> Color {
42 let default_colors = ColorTokens::default();
43 let colors = self
44 .tokens
45 .as_ref()
46 .map(|t| &t.colors)
47 .unwrap_or(&default_colors);
48
49 match &self.variant {
50 Variant::Primary => colors.primary.c50.clone(),
51 Variant::Secondary => colors.secondary.c50.clone(),
52 Variant::Success => colors.semantic.success.clone(),
53 Variant::Error => colors.semantic.error.clone(),
54 Variant::Warning => colors.semantic.warning.clone(),
55 Variant::Info => colors.semantic.info.clone(),
56 }
57 }
58
59 fn border_color(&self) -> Color {
60 let default_colors = ColorTokens::default();
61 let colors = self
62 .tokens
63 .as_ref()
64 .map(|t| &t.colors)
65 .unwrap_or(&default_colors);
66
67 match &self.variant {
68 Variant::Primary => colors.primary.c200.clone(),
69 Variant::Secondary => colors.secondary.c200.clone(),
70 Variant::Success => colors.semantic.success.clone(),
71 Variant::Error => colors.semantic.error.clone(),
72 Variant::Warning => colors.semantic.warning.clone(),
73 Variant::Info => colors.semantic.info.clone(),
74 }
75 }
76
77 fn text_color(&self) -> Color {
78 let default_colors = ColorTokens::default();
79 let colors = self
80 .tokens
81 .as_ref()
82 .map(|t| &t.colors)
83 .unwrap_or(&default_colors);
84
85 match &self.variant {
86 Variant::Primary => colors.primary.c900.clone(),
87 Variant::Secondary => colors.secondary.c900.clone(),
88 Variant::Success | Variant::Error | Variant::Warning | Variant::Info => {
89 colors.text.inverse.clone()
90 }
91 }
92 }
93
94 fn padding(&self) -> Spacing {
95 let default_spacing = SpacingTokens::default();
96 let spacing = self
97 .tokens
98 .as_ref()
99 .map(|t| &t.spacing)
100 .unwrap_or(&default_spacing);
101
102 match &self.size {
103 Size::Small => Spacing::all(spacing.sm.clone()),
104 Size::Medium => Spacing::all(spacing.md.clone()),
105 Size::Large => Spacing::all(spacing.lg.clone()),
106 Size::ExtraLarge => Spacing::all(spacing.xl.clone()),
107 }
108 }
109
110 fn border_radius(&self) -> Radius {
111 let default_borders = BorderTokens::default();
112 let borders = self
113 .tokens
114 .as_ref()
115 .map(|t| &t.borders)
116 .unwrap_or(&default_borders);
117
118 match &self.size {
119 Size::Small => Radius::all(borders.radius.sm.clone()),
120 Size::Medium => Radius::all(borders.radius.base.clone()),
121 Size::Large => Radius::all(borders.radius.lg.clone()),
122 Size::ExtraLarge => Radius::all(borders.radius.xl.clone()),
123 }
124 }
125}
126
127impl ComponentStyle for AlertStyle {
128 fn to_css(&self) -> String {
129 let mut css = String::new();
130
131 css.push_str(&format!(
132 "background-color: {}; ",
133 self.background_color().to_css()
134 ));
135 css.push_str(&format!(
136 "border: 1px solid {}; ",
137 self.border_color().to_css()
138 ));
139 css.push_str(&format!("border-left-width: 4px; "));
140 css.push_str(&format!("color: {}; ", self.text_color().to_css()));
141 css.push_str(&format!("padding: {}; ", self.padding().to_css()));
142 css.push_str(&format!(
143 "border-radius: {}; ",
144 self.border_radius().to_css()
145 ));
146 css.push_str("display: flex; ");
147 css.push_str("align-items: flex-start; ");
148 css.push_str("gap: 0.75rem; ");
149 css.push_str("margin-bottom: 1rem; ");
150
151 css
152 }
153
154 fn class_name(&self) -> &str {
155 "rustyle-alert"
156 }
157}
158
159impl Default for AlertStyle {
160 fn default() -> Self {
161 Self::new(Variant::Info, Size::Medium)
162 }
163}