tailwind_rs_core/utilities/
text_shadow.rs1use crate::classes::ClassBuilder;
7use serde::{Deserialize, Serialize};
8use std::fmt;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
12pub enum TextShadow {
13 None,
15 Sm,
17 Md,
19 Default,
21 Lg,
23 Xl,
25 Xl2,
27 Inner,
29}
30
31impl fmt::Display for TextShadow {
32 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33 match self {
34 TextShadow::None => write!(f, "none"),
35 TextShadow::Sm => write!(f, "0 1px 2px 0 rgb(0 0 0 / 0.05)"),
36 TextShadow::Md => write!(f, "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)"),
37 TextShadow::Default => write!(f, "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)"),
38 TextShadow::Lg => write!(f, "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)"),
39 TextShadow::Xl => write!(f, "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)"),
40 TextShadow::Xl2 => write!(f, "0 25px 50px -12px rgb(0 0 0 / 0.25)"),
41 TextShadow::Inner => write!(f, "inset 0 2px 4px 0 rgb(0 0 0 / 0.05)"),
42 }
43 }
44}
45
46impl TextShadow {
47 pub fn to_class_name(&self) -> String {
49 match self {
50 TextShadow::None => "text-shadow-none".to_string(),
51 TextShadow::Sm => "text-shadow-sm".to_string(),
52 TextShadow::Md => "text-shadow-md".to_string(),
53 TextShadow::Default => "text-shadow".to_string(),
54 TextShadow::Lg => "text-shadow-lg".to_string(),
55 TextShadow::Xl => "text-shadow-xl".to_string(),
56 TextShadow::Xl2 => "text-shadow-2xl".to_string(),
57 TextShadow::Inner => "text-shadow-inner".to_string(),
58 }
59 }
60
61 pub fn to_css_value(&self) -> String {
63 self.to_string()
64 }
65}
66
67pub trait TextShadowUtilities {
69 fn text_shadow_none(self) -> Self;
71 fn text_shadow_sm(self) -> Self;
73 fn text_shadow_md(self) -> Self;
75 fn text_shadow(self) -> Self;
77 fn text_shadow_lg(self) -> Self;
79 fn text_shadow_xl(self) -> Self;
81 fn text_shadow_2xl(self) -> Self;
83 fn text_shadow_inner(self) -> Self;
85 fn text_shadow_custom(self, shadow: TextShadow) -> Self;
87}
88
89impl TextShadowUtilities for ClassBuilder {
90 fn text_shadow_none(self) -> Self {
91 self.class("text-shadow-none")
92 }
93
94 fn text_shadow_sm(self) -> Self {
95 self.class("text-shadow-sm")
96 }
97
98 fn text_shadow_md(self) -> Self {
99 self.class("text-shadow-md")
100 }
101
102 fn text_shadow(self) -> Self {
103 self.class("text-shadow")
104 }
105
106 fn text_shadow_lg(self) -> Self {
107 self.class("text-shadow-lg")
108 }
109
110 fn text_shadow_xl(self) -> Self {
111 self.class("text-shadow-xl")
112 }
113
114 fn text_shadow_2xl(self) -> Self {
115 self.class("text-shadow-2xl")
116 }
117
118 fn text_shadow_inner(self) -> Self {
119 self.class("text-shadow-inner")
120 }
121
122 fn text_shadow_custom(self, shadow: TextShadow) -> Self {
123 self.class(&shadow.to_class_name())
124 }
125}
126
127#[cfg(test)]
128mod tests {
129 use super::*;
130 use crate::classes::ClassBuilder;
131
132 #[test]
133 fn test_text_shadow_enum_values() {
134 assert_eq!(TextShadow::None.to_string(), "none");
135 assert_eq!(TextShadow::Sm.to_string(), "0 1px 2px 0 rgb(0 0 0 / 0.05)");
136 assert_eq!(TextShadow::Default.to_string(), "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)");
137 assert_eq!(TextShadow::Lg.to_string(), "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)");
138 assert_eq!(TextShadow::Xl.to_string(), "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)");
139 assert_eq!(TextShadow::Xl2.to_string(), "0 25px 50px -12px rgb(0 0 0 / 0.25)");
140 assert_eq!(TextShadow::Inner.to_string(), "inset 0 2px 4px 0 rgb(0 0 0 / 0.05)");
141 }
142
143 #[test]
144 fn test_text_shadow_class_names() {
145 assert_eq!(TextShadow::None.to_class_name(), "text-shadow-none");
146 assert_eq!(TextShadow::Sm.to_class_name(), "text-shadow-sm");
147 assert_eq!(TextShadow::Default.to_class_name(), "text-shadow");
148 assert_eq!(TextShadow::Lg.to_class_name(), "text-shadow-lg");
149 assert_eq!(TextShadow::Xl.to_class_name(), "text-shadow-xl");
150 assert_eq!(TextShadow::Xl2.to_class_name(), "text-shadow-2xl");
151 assert_eq!(TextShadow::Inner.to_class_name(), "text-shadow-inner");
152 }
153
154 #[test]
155 fn test_text_shadow_utilities() {
156 let classes = ClassBuilder::new()
157 .text_shadow_none()
158 .text_shadow_sm()
159 .text_shadow()
160 .text_shadow_lg()
161 .text_shadow_xl()
162 .text_shadow_2xl()
163 .text_shadow_inner();
164
165 let result = classes.build();
166 assert!(result.classes.contains("text-shadow-none"));
167 assert!(result.classes.contains("text-shadow-sm"));
168 assert!(result.classes.contains("text-shadow"));
169 assert!(result.classes.contains("text-shadow-lg"));
170 assert!(result.classes.contains("text-shadow-xl"));
171 assert!(result.classes.contains("text-shadow-2xl"));
172 assert!(result.classes.contains("text-shadow-inner"));
173 }
174
175 #[test]
176 fn test_text_shadow_css_values() {
177 assert_eq!(TextShadow::None.to_css_value(), "none");
178 assert_eq!(TextShadow::Sm.to_css_value(), "0 1px 2px 0 rgb(0 0 0 / 0.05)");
179 assert_eq!(TextShadow::Default.to_css_value(), "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)");
180 assert_eq!(TextShadow::Lg.to_css_value(), "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)");
181 assert_eq!(TextShadow::Xl.to_css_value(), "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)");
182 assert_eq!(TextShadow::Xl2.to_css_value(), "0 25px 50px -12px rgb(0 0 0 / 0.25)");
183 assert_eq!(TextShadow::Inner.to_css_value(), "inset 0 2px 4px 0 rgb(0 0 0 / 0.05)");
184 }
185
186 #[test]
187 fn test_text_shadow_serialization() {
188 let shadow = TextShadow::Lg;
189 let serialized = serde_json::to_string(&shadow).unwrap();
190 let deserialized: TextShadow = serde_json::from_str(&serialized).unwrap();
191 assert_eq!(shadow, deserialized);
192 }
193
194 #[test]
195 fn test_text_shadow_comprehensive_usage() {
196 let classes = ClassBuilder::new()
197 .text_shadow_sm()
198 .text_shadow_lg();
199
200 let result = classes.build();
201 assert!(result.classes.contains("text-shadow-sm"));
202 assert!(result.classes.contains("text-shadow-lg"));
203 }
204
205 #[test]
206 fn test_text_shadow_custom_usage() {
207 let classes = ClassBuilder::new()
208 .text_shadow_custom(TextShadow::Xl)
209 .text_shadow_custom(TextShadow::Inner);
210
211 let result = classes.build();
212 assert!(result.classes.contains("text-shadow-xl"));
213 assert!(result.classes.contains("text-shadow-inner"));
214 }
215}