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