tailwind_rs_core/utilities/
typography.rs

1//! Typography utilities for tailwind-rs
2//!
3//! This module provides utilities for font families, font sizes, font weights,
4//! text alignment, line height, letter spacing, and other typography-related properties.
5
6use crate::classes::ClassBuilder;
7use serde::{Deserialize, Serialize};
8use std::fmt;
9
10/// Font family values
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
12pub enum FontFamily {
13    /// Sans-serif font family
14    Sans,
15    /// Serif font family
16    Serif,
17    /// Monospace font family
18    Mono,
19}
20
21/// Font size values
22#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
23pub enum FontSize {
24    /// Extra small font size
25    Xs,
26    /// Small font size
27    Sm,
28    /// Base font size
29    Base,
30    /// Large font size
31    Lg,
32    /// Extra large font size
33    Xl,
34    /// 2x large font size
35    Xl2,
36    /// 3x large font size
37    Xl3,
38    /// 4x large font size
39    Xl4,
40    /// 5x large font size
41    Xl5,
42    /// 6x large font size
43    Xl6,
44    /// 7x large font size
45    Xl7,
46    /// 8x large font size
47    Xl8,
48    /// 9x large font size
49    Xl9,
50}
51
52/// Font weight values
53#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
54pub enum FontWeight {
55    /// Thin font weight (100)
56    Thin,
57    /// Extra light font weight (200)
58    ExtraLight,
59    /// Light font weight (300)
60    Light,
61    /// Normal font weight (400)
62    Normal,
63    /// Medium font weight (500)
64    Medium,
65    /// Semi-bold font weight (600)
66    SemiBold,
67    /// Bold font weight (700)
68    Bold,
69    /// Extra bold font weight (800)
70    ExtraBold,
71    /// Black font weight (900)
72    Black,
73}
74
75/// Text alignment values
76#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
77pub enum TextAlign {
78    /// Left align
79    Left,
80    /// Center align
81    Center,
82    /// Right align
83    Right,
84    /// Justify align
85    Justify,
86    /// Start align (left in LTR, right in RTL)
87    Start,
88    /// End align (right in LTR, left in RTL)
89    End,
90}
91
92/// Line height values
93#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
94pub enum LineHeight {
95    /// None line height
96    None,
97    /// leading-3 (0.75rem / 12px)
98    Three,
99    /// leading-4 (1rem / 16px)
100    Four,
101    /// leading-5 (1.25rem / 20px)
102    Five,
103    /// leading-6 (1.5rem / 24px)
104    Six,
105    /// leading-7 (1.75rem / 28px)
106    Seven,
107    /// leading-8 (2rem / 32px)
108    Eight,
109    /// leading-9 (2.25rem / 36px)
110    Nine,
111    /// leading-10 (2.5rem / 40px)
112    Ten,
113    /// Tight line height
114    Tight,
115    /// Snug line height
116    Snug,
117    /// Normal line height
118    Normal,
119    /// Relaxed line height
120    Relaxed,
121    /// Loose line height
122    Loose,
123    /// Custom line height (f32)
124    Custom(f32),
125}
126
127/// Letter spacing values
128#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
129pub enum LetterSpacing {
130    /// Tighter letter spacing
131    Tighter,
132    /// Tight letter spacing
133    Tight,
134    /// Normal letter spacing
135    Normal,
136    /// Wide letter spacing
137    Wide,
138    /// Wider letter spacing
139    Wider,
140    /// Widest letter spacing
141    Widest,
142    /// Custom letter spacing (f32)
143    Custom(f32),
144}
145
146/// Text decoration values
147#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
148pub enum TextDecoration {
149    /// No decoration
150    None,
151    /// Underline decoration
152    Underline,
153    /// Overline decoration
154    Overline,
155    /// Line-through decoration
156    LineThrough,
157}
158
159/// Text decoration style values
160#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
161pub enum TextDecorationStyle {
162    /// Solid decoration style
163    Solid,
164    /// Double decoration style
165    Double,
166    /// Dotted decoration style
167    Dotted,
168    /// Dashed decoration style
169    Dashed,
170    /// Wavy decoration style
171    Wavy,
172}
173
174/// Text decoration thickness values
175#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
176pub enum TextDecorationThickness {
177    /// Auto thickness
178    Auto,
179    /// From font thickness
180    FromFont,
181    /// 0px thickness
182    Zero,
183    /// 1px thickness
184    One,
185    /// 2px thickness
186    Two,
187    /// 4px thickness
188    Four,
189    /// 8px thickness
190    Eight,
191}
192
193/// Text underline offset values
194#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
195pub enum TextUnderlineOffset {
196    /// Auto offset
197    Auto,
198    /// 0px offset
199    Zero,
200    /// 1px offset
201    One,
202    /// 2px offset
203    Two,
204    /// 4px offset
205    Four,
206    /// 8px offset
207    Eight,
208}
209
210/// Text transform values
211#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
212pub enum TextTransform {
213    /// No transform
214    None,
215    /// Uppercase transform
216    Uppercase,
217    /// Lowercase transform
218    Lowercase,
219    /// Capitalize transform
220    Capitalize,
221}
222
223/// Text overflow values
224#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
225pub enum TextOverflow {
226    /// Truncate text overflow
227    Truncate,
228    /// Ellipsis text overflow
229    Ellipsis,
230    /// Clip text overflow
231    Clip,
232}
233
234/// White space values
235#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
236pub enum WhiteSpace {
237    /// Normal white space
238    Normal,
239    /// Nowrap white space
240    Nowrap,
241    /// Pre white space
242    Pre,
243    /// Pre-line white space
244    PreLine,
245    /// Pre-wrap white space
246    PreWrap,
247    /// Break-spaces white space
248    BreakSpaces,
249}
250
251/// Word break values
252#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
253pub enum WordBreak {
254    /// Normal word break
255    Normal,
256    /// Break-all word break
257    BreakAll,
258    /// Break-words word break
259    BreakWords,
260    /// Keep-all word break
261    KeepAll,
262}
263
264/// Overflow wrap values
265#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
266pub enum OverflowWrap {
267    /// Normal overflow wrap
268    Normal,
269    /// Break-word overflow wrap
270    BreakWord,
271    /// Anywhere overflow wrap
272    Anywhere,
273}
274
275impl std::hash::Hash for LineHeight {
276    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
277        match self {
278            LineHeight::None => 0u8.hash(state),
279            LineHeight::Three => 1u8.hash(state),
280            LineHeight::Four => 2u8.hash(state),
281            LineHeight::Five => 3u8.hash(state),
282            LineHeight::Six => 4u8.hash(state),
283            LineHeight::Seven => 5u8.hash(state),
284            LineHeight::Eight => 6u8.hash(state),
285            LineHeight::Nine => 7u8.hash(state),
286            LineHeight::Ten => 8u8.hash(state),
287            LineHeight::Tight => 9u8.hash(state),
288            LineHeight::Snug => 10u8.hash(state),
289            LineHeight::Normal => 11u8.hash(state),
290            LineHeight::Relaxed => 12u8.hash(state),
291            LineHeight::Loose => 13u8.hash(state),
292            LineHeight::Custom(f) => {
293                14u8.hash(state);
294                ((f * 1000.0) as u32).hash(state);
295            }
296        }
297    }
298}
299
300impl std::hash::Hash for LetterSpacing {
301    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
302        match self {
303            LetterSpacing::Tighter => 0u8.hash(state),
304            LetterSpacing::Tight => 1u8.hash(state),
305            LetterSpacing::Normal => 2u8.hash(state),
306            LetterSpacing::Wide => 3u8.hash(state),
307            LetterSpacing::Wider => 4u8.hash(state),
308            LetterSpacing::Widest => 5u8.hash(state),
309            LetterSpacing::Custom(f) => {
310                6u8.hash(state);
311                ((f * 1000.0) as u32).hash(state);
312            }
313        }
314    }
315}
316
317impl std::cmp::Eq for LineHeight {}
318impl std::cmp::Eq for LetterSpacing {}
319
320impl FontFamily {
321    pub fn to_class_name(&self) -> String {
322        match self {
323            FontFamily::Sans => "sans".to_string(),
324            FontFamily::Serif => "serif".to_string(),
325            FontFamily::Mono => "mono".to_string(),
326        }
327    }
328    
329    pub fn to_css_value(&self) -> String {
330        match self {
331            FontFamily::Sans => "ui-sans-serif, system-ui, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\"".to_string(),
332            FontFamily::Serif => "ui-serif, Georgia, Cambria, \"Times New Roman\", Times, serif".to_string(),
333            FontFamily::Mono => "ui-monospace, SFMono-Regular, \"SF Mono\", Consolas, \"Liberation Mono\", Menlo, monospace".to_string(),
334        }
335    }
336}
337
338impl FontSize {
339    pub fn to_class_name(&self) -> String {
340        match self {
341            FontSize::Xs => "xs".to_string(),
342            FontSize::Sm => "sm".to_string(),
343            FontSize::Base => "base".to_string(),
344            FontSize::Lg => "lg".to_string(),
345            FontSize::Xl => "xl".to_string(),
346            FontSize::Xl2 => "2xl".to_string(),
347            FontSize::Xl3 => "3xl".to_string(),
348            FontSize::Xl4 => "4xl".to_string(),
349            FontSize::Xl5 => "5xl".to_string(),
350            FontSize::Xl6 => "6xl".to_string(),
351            FontSize::Xl7 => "7xl".to_string(),
352            FontSize::Xl8 => "8xl".to_string(),
353            FontSize::Xl9 => "9xl".to_string(),
354        }
355    }
356    
357    pub fn to_css_value(&self) -> String {
358        match self {
359            FontSize::Xs => "0.75rem".to_string(),
360            FontSize::Sm => "0.875rem".to_string(),
361            FontSize::Base => "1rem".to_string(),
362            FontSize::Lg => "1.125rem".to_string(),
363            FontSize::Xl => "1.25rem".to_string(),
364            FontSize::Xl2 => "1.5rem".to_string(),
365            FontSize::Xl3 => "1.875rem".to_string(),
366            FontSize::Xl4 => "2.25rem".to_string(),
367            FontSize::Xl5 => "3rem".to_string(),
368            FontSize::Xl6 => "3.75rem".to_string(),
369            FontSize::Xl7 => "4.5rem".to_string(),
370            FontSize::Xl8 => "6rem".to_string(),
371            FontSize::Xl9 => "8rem".to_string(),
372        }
373    }
374}
375
376impl FontWeight {
377    pub fn to_class_name(&self) -> String {
378        match self {
379            FontWeight::Thin => "thin".to_string(),
380            FontWeight::ExtraLight => "extralight".to_string(),
381            FontWeight::Light => "light".to_string(),
382            FontWeight::Normal => "normal".to_string(),
383            FontWeight::Medium => "medium".to_string(),
384            FontWeight::SemiBold => "semibold".to_string(),
385            FontWeight::Bold => "bold".to_string(),
386            FontWeight::ExtraBold => "extrabold".to_string(),
387            FontWeight::Black => "black".to_string(),
388        }
389    }
390    
391    pub fn to_css_value(&self) -> String {
392        match self {
393            FontWeight::Thin => "100".to_string(),
394            FontWeight::ExtraLight => "200".to_string(),
395            FontWeight::Light => "300".to_string(),
396            FontWeight::Normal => "400".to_string(),
397            FontWeight::Medium => "500".to_string(),
398            FontWeight::SemiBold => "600".to_string(),
399            FontWeight::Bold => "700".to_string(),
400            FontWeight::ExtraBold => "800".to_string(),
401            FontWeight::Black => "900".to_string(),
402        }
403    }
404}
405
406impl TextAlign {
407    pub fn to_class_name(&self) -> String {
408        match self {
409            TextAlign::Left => "left".to_string(),
410            TextAlign::Center => "center".to_string(),
411            TextAlign::Right => "right".to_string(),
412            TextAlign::Justify => "justify".to_string(),
413            TextAlign::Start => "start".to_string(),
414            TextAlign::End => "end".to_string(),
415        }
416    }
417    
418    pub fn to_css_value(&self) -> String {
419        match self {
420            TextAlign::Left => "left".to_string(),
421            TextAlign::Center => "center".to_string(),
422            TextAlign::Right => "right".to_string(),
423            TextAlign::Justify => "justify".to_string(),
424            TextAlign::Start => "start".to_string(),
425            TextAlign::End => "end".to_string(),
426        }
427    }
428}
429
430impl LineHeight {
431    pub fn to_class_name(&self) -> String {
432        match self {
433            LineHeight::None => "none".to_string(),
434            LineHeight::Three => "3".to_string(),
435            LineHeight::Four => "4".to_string(),
436            LineHeight::Five => "5".to_string(),
437            LineHeight::Six => "6".to_string(),
438            LineHeight::Seven => "7".to_string(),
439            LineHeight::Eight => "8".to_string(),
440            LineHeight::Nine => "9".to_string(),
441            LineHeight::Ten => "10".to_string(),
442            LineHeight::Tight => "tight".to_string(),
443            LineHeight::Snug => "snug".to_string(),
444            LineHeight::Normal => "normal".to_string(),
445            LineHeight::Relaxed => "relaxed".to_string(),
446            LineHeight::Loose => "loose".to_string(),
447            LineHeight::Custom(f) => format!("{}", f),
448        }
449    }
450
451    pub fn to_css_value(&self) -> String {
452        match self {
453            LineHeight::None => "1".to_string(),
454            LineHeight::Three => "0.75rem".to_string(),
455            LineHeight::Four => "1rem".to_string(),
456            LineHeight::Five => "1.25rem".to_string(),
457            LineHeight::Six => "1.5rem".to_string(),
458            LineHeight::Seven => "1.75rem".to_string(),
459            LineHeight::Eight => "2rem".to_string(),
460            LineHeight::Nine => "2.25rem".to_string(),
461            LineHeight::Ten => "2.5rem".to_string(),
462            LineHeight::Tight => "1.25".to_string(),
463            LineHeight::Snug => "1.375".to_string(),
464            LineHeight::Normal => "1.5".to_string(),
465            LineHeight::Relaxed => "1.625".to_string(),
466            LineHeight::Loose => "2".to_string(),
467            LineHeight::Custom(f) => f.to_string(),
468        }
469    }
470
471    /// Get all available line height values
472    pub fn all_values() -> Vec<LineHeight> {
473        vec![
474            LineHeight::None,
475            LineHeight::Three,
476            LineHeight::Four,
477            LineHeight::Five,
478            LineHeight::Six,
479            LineHeight::Seven,
480            LineHeight::Eight,
481            LineHeight::Nine,
482            LineHeight::Ten,
483            LineHeight::Tight,
484            LineHeight::Snug,
485            LineHeight::Normal,
486            LineHeight::Relaxed,
487            LineHeight::Loose,
488        ]
489    }
490}
491
492impl LetterSpacing {
493    pub fn to_class_name(&self) -> String {
494        match self {
495            LetterSpacing::Tighter => "tighter".to_string(),
496            LetterSpacing::Tight => "tight".to_string(),
497            LetterSpacing::Normal => "normal".to_string(),
498            LetterSpacing::Wide => "wide".to_string(),
499            LetterSpacing::Wider => "wider".to_string(),
500            LetterSpacing::Widest => "widest".to_string(),
501            LetterSpacing::Custom(f) => format!("{}", f),
502        }
503    }
504    
505    pub fn to_css_value(&self) -> String {
506        match self {
507            LetterSpacing::Tighter => "-0.05em".to_string(),
508            LetterSpacing::Tight => "-0.025em".to_string(),
509            LetterSpacing::Normal => "0em".to_string(),
510            LetterSpacing::Wide => "0.025em".to_string(),
511            LetterSpacing::Wider => "0.05em".to_string(),
512            LetterSpacing::Widest => "0.1em".to_string(),
513            LetterSpacing::Custom(f) => format!("{}em", f),
514        }
515    }
516}
517
518impl TextDecoration {
519    pub fn to_class_name(&self) -> String {
520        match self {
521            TextDecoration::None => "no-underline".to_string(),
522            TextDecoration::Underline => "underline".to_string(),
523            TextDecoration::Overline => "overline".to_string(),
524            TextDecoration::LineThrough => "line-through".to_string(),
525        }
526    }
527
528    pub fn to_css_value(&self) -> String {
529        match self {
530            TextDecoration::None => "none".to_string(),
531            TextDecoration::Underline => "underline".to_string(),
532            TextDecoration::Overline => "overline".to_string(),
533            TextDecoration::LineThrough => "line-through".to_string(),
534        }
535    }
536}
537
538impl TextDecorationStyle {
539    pub fn to_class_name(&self) -> String {
540        match self {
541            TextDecorationStyle::Solid => "decoration-solid".to_string(),
542            TextDecorationStyle::Double => "decoration-double".to_string(),
543            TextDecorationStyle::Dotted => "decoration-dotted".to_string(),
544            TextDecorationStyle::Dashed => "decoration-dashed".to_string(),
545            TextDecorationStyle::Wavy => "decoration-wavy".to_string(),
546        }
547    }
548
549    pub fn to_css_value(&self) -> String {
550        match self {
551            TextDecorationStyle::Solid => "solid".to_string(),
552            TextDecorationStyle::Double => "double".to_string(),
553            TextDecorationStyle::Dotted => "dotted".to_string(),
554            TextDecorationStyle::Dashed => "dashed".to_string(),
555            TextDecorationStyle::Wavy => "wavy".to_string(),
556        }
557    }
558}
559
560impl TextDecorationThickness {
561    pub fn to_class_name(&self) -> String {
562        match self {
563            TextDecorationThickness::Auto => "decoration-auto".to_string(),
564            TextDecorationThickness::FromFont => "decoration-from-font".to_string(),
565            TextDecorationThickness::Zero => "decoration-0".to_string(),
566            TextDecorationThickness::One => "decoration-1".to_string(),
567            TextDecorationThickness::Two => "decoration-2".to_string(),
568            TextDecorationThickness::Four => "decoration-4".to_string(),
569            TextDecorationThickness::Eight => "decoration-8".to_string(),
570        }
571    }
572
573    pub fn to_css_value(&self) -> String {
574        match self {
575            TextDecorationThickness::Auto => "auto".to_string(),
576            TextDecorationThickness::FromFont => "from-font".to_string(),
577            TextDecorationThickness::Zero => "0px".to_string(),
578            TextDecorationThickness::One => "1px".to_string(),
579            TextDecorationThickness::Two => "2px".to_string(),
580            TextDecorationThickness::Four => "4px".to_string(),
581            TextDecorationThickness::Eight => "8px".to_string(),
582        }
583    }
584}
585
586impl TextUnderlineOffset {
587    pub fn to_class_name(&self) -> String {
588        match self {
589            TextUnderlineOffset::Auto => "underline-offset-auto".to_string(),
590            TextUnderlineOffset::Zero => "underline-offset-0".to_string(),
591            TextUnderlineOffset::One => "underline-offset-1".to_string(),
592            TextUnderlineOffset::Two => "underline-offset-2".to_string(),
593            TextUnderlineOffset::Four => "underline-offset-4".to_string(),
594            TextUnderlineOffset::Eight => "underline-offset-8".to_string(),
595        }
596    }
597
598    pub fn to_css_value(&self) -> String {
599        match self {
600            TextUnderlineOffset::Auto => "auto".to_string(),
601            TextUnderlineOffset::Zero => "0px".to_string(),
602            TextUnderlineOffset::One => "1px".to_string(),
603            TextUnderlineOffset::Two => "2px".to_string(),
604            TextUnderlineOffset::Four => "4px".to_string(),
605            TextUnderlineOffset::Eight => "8px".to_string(),
606        }
607    }
608}
609
610impl TextTransform {
611    pub fn to_class_name(&self) -> String {
612        match self {
613            TextTransform::None => "normal-case".to_string(),
614            TextTransform::Uppercase => "uppercase".to_string(),
615            TextTransform::Lowercase => "lowercase".to_string(),
616            TextTransform::Capitalize => "capitalize".to_string(),
617        }
618    }
619    
620    pub fn to_css_value(&self) -> String {
621        match self {
622            TextTransform::None => "none".to_string(),
623            TextTransform::Uppercase => "uppercase".to_string(),
624            TextTransform::Lowercase => "lowercase".to_string(),
625            TextTransform::Capitalize => "capitalize".to_string(),
626        }
627    }
628}
629
630impl TextOverflow {
631    pub fn to_class_name(&self) -> String {
632        match self {
633            TextOverflow::Truncate => "truncate".to_string(),
634            TextOverflow::Ellipsis => "text-ellipsis".to_string(),
635            TextOverflow::Clip => "text-clip".to_string(),
636        }
637    }
638    
639    pub fn to_css_value(&self) -> String {
640        match self {
641            TextOverflow::Truncate => "truncate".to_string(),
642            TextOverflow::Ellipsis => "ellipsis".to_string(),
643            TextOverflow::Clip => "clip".to_string(),
644        }
645    }
646}
647
648impl WhiteSpace {
649    pub fn to_class_name(&self) -> String {
650        match self {
651            WhiteSpace::Normal => "whitespace-normal".to_string(),
652            WhiteSpace::Nowrap => "whitespace-nowrap".to_string(),
653            WhiteSpace::Pre => "whitespace-pre".to_string(),
654            WhiteSpace::PreLine => "whitespace-pre-line".to_string(),
655            WhiteSpace::PreWrap => "whitespace-pre-wrap".to_string(),
656            WhiteSpace::BreakSpaces => "whitespace-break-spaces".to_string(),
657        }
658    }
659    
660    pub fn to_css_value(&self) -> String {
661        match self {
662            WhiteSpace::Normal => "normal".to_string(),
663            WhiteSpace::Nowrap => "nowrap".to_string(),
664            WhiteSpace::Pre => "pre".to_string(),
665            WhiteSpace::PreLine => "pre-line".to_string(),
666            WhiteSpace::PreWrap => "pre-wrap".to_string(),
667            WhiteSpace::BreakSpaces => "break-spaces".to_string(),
668        }
669    }
670}
671
672impl WordBreak {
673    pub fn to_class_name(&self) -> String {
674        match self {
675            WordBreak::Normal => "break-normal".to_string(),
676            WordBreak::BreakAll => "break-all".to_string(),
677            WordBreak::BreakWords => "break-words".to_string(),
678            WordBreak::KeepAll => "break-keep".to_string(),
679        }
680    }
681    
682    pub fn to_css_value(&self) -> String {
683        match self {
684            WordBreak::Normal => "normal".to_string(),
685            WordBreak::BreakAll => "break-all".to_string(),
686            WordBreak::BreakWords => "break-words".to_string(),
687            WordBreak::KeepAll => "keep-all".to_string(),
688        }
689    }
690}
691
692impl OverflowWrap {
693    pub fn to_class_name(&self) -> String {
694        match self {
695            OverflowWrap::Normal => "overflow-wrap-normal".to_string(),
696            OverflowWrap::BreakWord => "overflow-wrap-break".to_string(),
697            OverflowWrap::Anywhere => "overflow-wrap-anywhere".to_string(),
698        }
699    }
700    
701    pub fn to_css_value(&self) -> String {
702        match self {
703            OverflowWrap::Normal => "normal".to_string(),
704            OverflowWrap::BreakWord => "break-word".to_string(),
705            OverflowWrap::Anywhere => "anywhere".to_string(),
706        }
707    }
708}
709
710impl fmt::Display for FontFamily {
711    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
712        write!(f, "{}", self.to_class_name())
713    }
714}
715
716impl fmt::Display for FontSize {
717    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
718        write!(f, "{}", self.to_class_name())
719    }
720}
721
722impl fmt::Display for FontWeight {
723    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
724        write!(f, "{}", self.to_class_name())
725    }
726}
727
728impl fmt::Display for TextAlign {
729    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
730        write!(f, "{}", self.to_class_name())
731    }
732}
733
734impl fmt::Display for LineHeight {
735    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
736        write!(f, "{}", self.to_class_name())
737    }
738}
739
740impl fmt::Display for LetterSpacing {
741    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
742        write!(f, "{}", self.to_class_name())
743    }
744}
745
746impl fmt::Display for TextDecoration {
747    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
748        write!(f, "{}", self.to_class_name())
749    }
750}
751
752impl fmt::Display for TextDecorationStyle {
753    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
754        write!(f, "{}", self.to_class_name())
755    }
756}
757
758impl fmt::Display for TextDecorationThickness {
759    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
760        write!(f, "{}", self.to_class_name())
761    }
762}
763
764impl fmt::Display for TextUnderlineOffset {
765    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
766        write!(f, "{}", self.to_class_name())
767    }
768}
769
770impl fmt::Display for TextTransform {
771    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
772        write!(f, "{}", self.to_class_name())
773    }
774}
775
776impl fmt::Display for OverflowWrap {
777    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
778        write!(f, "{}", self.to_class_name())
779    }
780}
781
782/// Trait for adding font family utilities to a class builder
783pub trait FontFamilyUtilities {
784    /// Set font family
785    fn font_family(self, family: FontFamily) -> Self;
786}
787
788impl FontFamilyUtilities for ClassBuilder {
789    fn font_family(self, family: FontFamily) -> Self {
790        self.class(format!("font-{}", family.to_class_name()))
791    }
792}
793
794/// Trait for adding font size utilities to a class builder
795pub trait FontSizeUtilities {
796    /// Set font size
797    fn font_size(self, size: FontSize) -> Self;
798}
799
800impl FontSizeUtilities for ClassBuilder {
801    fn font_size(self, size: FontSize) -> Self {
802        self.class(format!("text-{}", size.to_class_name()))
803    }
804}
805
806/// Trait for adding font weight utilities to a class builder
807pub trait FontWeightUtilities {
808    /// Set font weight
809    fn font_weight(self, weight: FontWeight) -> Self;
810}
811
812impl FontWeightUtilities for ClassBuilder {
813    fn font_weight(self, weight: FontWeight) -> Self {
814        self.class(format!("font-{}", weight.to_class_name()))
815    }
816}
817
818/// Trait for adding text alignment utilities to a class builder
819pub trait TextAlignUtilities {
820    /// Set text alignment
821    fn text_align(self, align: TextAlign) -> Self;
822}
823
824impl TextAlignUtilities for ClassBuilder {
825    fn text_align(self, align: TextAlign) -> Self {
826        self.class(format!("text-{}", align.to_class_name()))
827    }
828}
829
830/// Trait for adding line height utilities to a class builder
831pub trait LineHeightUtilities {
832    /// Set line height
833    fn line_height(self, height: LineHeight) -> Self;
834}
835
836impl LineHeightUtilities for ClassBuilder {
837    fn line_height(self, height: LineHeight) -> Self {
838        self.class(format!("leading-{}", height.to_class_name()))
839    }
840}
841
842/// Trait for adding letter spacing utilities to a class builder
843pub trait LetterSpacingUtilities {
844    /// Set letter spacing
845    fn letter_spacing(self, spacing: LetterSpacing) -> Self;
846}
847
848impl LetterSpacingUtilities for ClassBuilder {
849    fn letter_spacing(self, spacing: LetterSpacing) -> Self {
850        self.class(format!("tracking-{}", spacing.to_class_name()))
851    }
852}
853
854/// Trait for adding text decoration utilities to a class builder
855pub trait TextDecorationUtilities {
856    /// Set text decoration
857    fn text_decoration(self, decoration: TextDecoration) -> Self;
858}
859
860impl TextDecorationUtilities for ClassBuilder {
861    fn text_decoration(self, decoration: TextDecoration) -> Self {
862        self.class(decoration.to_class_name())
863    }
864}
865
866/// Trait for adding text transform utilities to a class builder
867pub trait TextTransformUtilities {
868    /// Set text transform
869    fn text_transform(self, transform: TextTransform) -> Self;
870}
871
872impl TextTransformUtilities for ClassBuilder {
873    fn text_transform(self, transform: TextTransform) -> Self {
874        self.class(transform.to_class_name())
875    }
876}
877
878/// Trait for adding text overflow utilities to a class builder
879pub trait TextOverflowUtilities {
880    /// Set text overflow
881    fn text_overflow(self, overflow: TextOverflow) -> Self;
882}
883
884impl TextOverflowUtilities for ClassBuilder {
885    fn text_overflow(self, overflow: TextOverflow) -> Self {
886        self.class(overflow.to_class_name())
887    }
888}
889
890/// Trait for adding white space utilities to a class builder
891pub trait WhiteSpaceUtilities {
892    /// Set white space
893    fn white_space(self, space: WhiteSpace) -> Self;
894}
895
896impl WhiteSpaceUtilities for ClassBuilder {
897    fn white_space(self, space: WhiteSpace) -> Self {
898        self.class(space.to_class_name())
899    }
900}
901
902/// Trait for adding word break utilities to a class builder
903pub trait WordBreakUtilities {
904    /// Set word break
905    fn word_break(self, break_type: WordBreak) -> Self;
906}
907
908impl WordBreakUtilities for ClassBuilder {
909    fn word_break(self, break_type: WordBreak) -> Self {
910        self.class(break_type.to_class_name())
911    }
912}
913
914/// Trait for adding overflow wrap utilities to a class builder
915pub trait OverflowWrapUtilities {
916    /// Set overflow wrap
917    fn overflow_wrap(self, wrap_type: OverflowWrap) -> Self;
918}
919
920impl OverflowWrapUtilities for ClassBuilder {
921    fn overflow_wrap(self, wrap_type: OverflowWrap) -> Self {
922        self.class(wrap_type.to_class_name())
923    }
924}
925
926/// Trait for adding text decoration style utilities to a class builder
927pub trait TextDecorationStyleUtilities {
928    /// Set text decoration style
929    fn text_decoration_style(self, style: TextDecorationStyle) -> Self;
930}
931
932impl TextDecorationStyleUtilities for ClassBuilder {
933    fn text_decoration_style(self, style: TextDecorationStyle) -> Self {
934        self.class(style.to_class_name())
935    }
936}
937
938/// Trait for adding text decoration thickness utilities to a class builder
939pub trait TextDecorationThicknessUtilities {
940    /// Set text decoration thickness
941    fn text_decoration_thickness(self, thickness: TextDecorationThickness) -> Self;
942}
943
944impl TextDecorationThicknessUtilities for ClassBuilder {
945    fn text_decoration_thickness(self, thickness: TextDecorationThickness) -> Self {
946        self.class(thickness.to_class_name())
947    }
948}
949
950/// Trait for adding text underline offset utilities to a class builder
951pub trait TextUnderlineOffsetUtilities {
952    /// Set text underline offset
953    fn text_underline_offset(self, offset: TextUnderlineOffset) -> Self;
954}
955
956impl TextUnderlineOffsetUtilities for ClassBuilder {
957    fn text_underline_offset(self, offset: TextUnderlineOffset) -> Self {
958        self.class(offset.to_class_name())
959    }
960}
961
962#[cfg(test)]
963mod tests {
964    use super::*;
965    
966    #[test]
967    fn test_font_family_utilities() {
968        let classes = ClassBuilder::new()
969            .font_family(FontFamily::Sans)
970            .font_family(FontFamily::Serif)
971            .font_family(FontFamily::Mono)
972            .build();
973        
974        let css_classes = classes.to_css_classes();
975        assert!(css_classes.contains("font-sans"));
976        assert!(css_classes.contains("font-serif"));
977        assert!(css_classes.contains("font-mono"));
978    }
979    
980    #[test]
981    fn test_font_size_utilities() {
982        let classes = ClassBuilder::new()
983            .font_size(FontSize::Xs)
984            .font_size(FontSize::Sm)
985            .font_size(FontSize::Base)
986            .font_size(FontSize::Lg)
987            .font_size(FontSize::Xl)
988            .build();
989        
990        let css_classes = classes.to_css_classes();
991        assert!(css_classes.contains("text-xs"));
992        assert!(css_classes.contains("text-sm"));
993        assert!(css_classes.contains("text-base"));
994        assert!(css_classes.contains("text-lg"));
995        assert!(css_classes.contains("text-xl"));
996    }
997    
998    #[test]
999    fn test_font_weight_utilities() {
1000        let classes = ClassBuilder::new()
1001            .font_weight(FontWeight::Thin)
1002            .font_weight(FontWeight::Normal)
1003            .font_weight(FontWeight::Bold)
1004            .font_weight(FontWeight::Black)
1005            .build();
1006        
1007        let css_classes = classes.to_css_classes();
1008        assert!(css_classes.contains("font-thin"));
1009        assert!(css_classes.contains("font-normal"));
1010        assert!(css_classes.contains("font-bold"));
1011        assert!(css_classes.contains("font-black"));
1012    }
1013    
1014    #[test]
1015    fn test_text_align_utilities() {
1016        let classes = ClassBuilder::new()
1017            .text_align(TextAlign::Left)
1018            .text_align(TextAlign::Center)
1019            .text_align(TextAlign::Right)
1020            .text_align(TextAlign::Justify)
1021            .build();
1022        
1023        let css_classes = classes.to_css_classes();
1024        assert!(css_classes.contains("text-left"));
1025        assert!(css_classes.contains("text-center"));
1026        assert!(css_classes.contains("text-right"));
1027        assert!(css_classes.contains("text-justify"));
1028    }
1029    
1030    #[test]
1031    fn test_line_height_utilities() {
1032        let classes = ClassBuilder::new()
1033            .line_height(LineHeight::Tight)
1034            .line_height(LineHeight::Normal)
1035            .line_height(LineHeight::Relaxed)
1036            .line_height(LineHeight::Custom(1.75))
1037            .build();
1038        
1039        let css_classes = classes.to_css_classes();
1040        assert!(css_classes.contains("leading-tight"));
1041        assert!(css_classes.contains("leading-normal"));
1042        assert!(css_classes.contains("leading-relaxed"));
1043        assert!(css_classes.contains("leading-1.75"));
1044    }
1045    
1046    #[test]
1047    fn test_letter_spacing_utilities() {
1048        let classes = ClassBuilder::new()
1049            .letter_spacing(LetterSpacing::Tight)
1050            .letter_spacing(LetterSpacing::Normal)
1051            .letter_spacing(LetterSpacing::Wide)
1052            .letter_spacing(LetterSpacing::Custom(0.1))
1053            .build();
1054        
1055        let css_classes = classes.to_css_classes();
1056        assert!(css_classes.contains("tracking-tight"));
1057        assert!(css_classes.contains("tracking-normal"));
1058        assert!(css_classes.contains("tracking-wide"));
1059        assert!(css_classes.contains("tracking-0.1"));
1060    }
1061    
1062    #[test]
1063    fn test_text_decoration_utilities() {
1064        let classes = ClassBuilder::new()
1065            .text_decoration(TextDecoration::None)
1066            .text_decoration(TextDecoration::Underline)
1067            .text_decoration(TextDecoration::LineThrough)
1068            .build();
1069        
1070        let css_classes = classes.to_css_classes();
1071        assert!(css_classes.contains("no-underline"));
1072        assert!(css_classes.contains("underline"));
1073        assert!(css_classes.contains("line-through"));
1074    }
1075    
1076    #[test]
1077    fn test_text_transform_utilities() {
1078        let classes = ClassBuilder::new()
1079            .text_transform(TextTransform::None)
1080            .text_transform(TextTransform::Uppercase)
1081            .text_transform(TextTransform::Lowercase)
1082            .text_transform(TextTransform::Capitalize)
1083            .build();
1084        
1085        let css_classes = classes.to_css_classes();
1086        assert!(css_classes.contains("normal-case"));
1087        assert!(css_classes.contains("uppercase"));
1088        assert!(css_classes.contains("lowercase"));
1089        assert!(css_classes.contains("capitalize"));
1090    }
1091    
1092    #[test]
1093    fn test_text_overflow_utilities() {
1094        let classes = ClassBuilder::new()
1095            .text_overflow(TextOverflow::Truncate)
1096            .text_overflow(TextOverflow::Ellipsis)
1097            .text_overflow(TextOverflow::Clip)
1098            .build();
1099        
1100        let css_classes = classes.to_css_classes();
1101        assert!(css_classes.contains("truncate"));
1102        assert!(css_classes.contains("text-ellipsis"));
1103        assert!(css_classes.contains("text-clip"));
1104    }
1105    
1106    #[test]
1107    fn test_white_space_utilities() {
1108        let classes = ClassBuilder::new()
1109            .white_space(WhiteSpace::Normal)
1110            .white_space(WhiteSpace::Nowrap)
1111            .white_space(WhiteSpace::Pre)
1112            .build();
1113        
1114        let css_classes = classes.to_css_classes();
1115        assert!(css_classes.contains("whitespace-normal"));
1116        assert!(css_classes.contains("whitespace-nowrap"));
1117        assert!(css_classes.contains("whitespace-pre"));
1118    }
1119    
1120    #[test]
1121    fn test_word_break_utilities() {
1122        let classes = ClassBuilder::new()
1123            .word_break(WordBreak::Normal)
1124            .word_break(WordBreak::BreakAll)
1125            .word_break(WordBreak::BreakWords)
1126            .build();
1127        
1128        let css_classes = classes.to_css_classes();
1129        assert!(css_classes.contains("break-normal"));
1130        assert!(css_classes.contains("break-all"));
1131        assert!(css_classes.contains("break-words"));
1132    }
1133    
1134    #[test]
1135    fn test_complex_typography_combination() {
1136        let classes = ClassBuilder::new()
1137            .font_family(FontFamily::Sans)
1138            .font_size(FontSize::Lg)
1139            .font_weight(FontWeight::Bold)
1140            .text_align(TextAlign::Center)
1141            .line_height(LineHeight::Relaxed)
1142            .letter_spacing(LetterSpacing::Wide)
1143            .text_decoration(TextDecoration::Underline)
1144            .text_transform(TextTransform::Uppercase)
1145            .build();
1146        
1147        let css_classes = classes.to_css_classes();
1148        assert!(css_classes.contains("font-sans"));
1149        assert!(css_classes.contains("text-lg"));
1150        assert!(css_classes.contains("font-bold"));
1151        assert!(css_classes.contains("text-center"));
1152        assert!(css_classes.contains("leading-relaxed"));
1153        assert!(css_classes.contains("tracking-wide"));
1154        assert!(css_classes.contains("underline"));
1155        assert!(css_classes.contains("uppercase"));
1156    }
1157    
1158    /// Test that all Tailwind CSS font sizes are supported
1159    #[test]
1160    fn test_all_tailwind_font_sizes() {
1161        // Test all standard Tailwind CSS font sizes (text-xs through text-9xl)
1162        let test_values = vec![
1163            (FontSize::Xs, "text-xs"),
1164            (FontSize::Sm, "text-sm"),
1165            (FontSize::Base, "text-base"),
1166            (FontSize::Lg, "text-lg"),
1167            (FontSize::Xl, "text-xl"),
1168            (FontSize::Xl2, "text-2xl"),
1169            (FontSize::Xl3, "text-3xl"),
1170            (FontSize::Xl4, "text-4xl"),
1171            (FontSize::Xl5, "text-5xl"),
1172            (FontSize::Xl6, "text-6xl"),
1173            (FontSize::Xl7, "text-7xl"),
1174            (FontSize::Xl8, "text-8xl"),
1175            (FontSize::Xl9, "text-9xl"),
1176        ];
1177        
1178        for (value, expected_class) in test_values {
1179            let classes = ClassBuilder::new().font_size(value).build();
1180            let css_classes = classes.to_css_classes();
1181            assert!(css_classes.contains(expected_class), 
1182                "Missing font size: {} (expected class: {})", 
1183                format!("{:?}", value), expected_class);
1184        }
1185    }
1186    
1187    /// Test that all Week 4 typography utilities are implemented
1188    #[test]
1189    fn test_week4_typography_utilities() {
1190        // Test all Week 4 typography utilities
1191        let classes = ClassBuilder::new()
1192            // Font sizes (text-xs through text-9xl) - already tested above
1193            .font_size(FontSize::Xs)
1194            .font_size(FontSize::Xl9)
1195            // Font weights (font-thin through font-black)
1196            .font_weight(FontWeight::Thin)
1197            .font_weight(FontWeight::Black)
1198            // Line heights (leading-3 through leading-10)
1199            .line_height(LineHeight::Tight)
1200            .line_height(LineHeight::Relaxed)
1201            // Letter spacing (tracking-tighter through tracking-widest)
1202            .letter_spacing(LetterSpacing::Tighter)
1203            .letter_spacing(LetterSpacing::Widest)
1204            // Text decoration (underline, no-underline, line-through)
1205            .text_decoration(TextDecoration::Underline)
1206            .text_decoration(TextDecoration::None)
1207            .text_decoration(TextDecoration::LineThrough)
1208            // Text transform (uppercase, lowercase, capitalize)
1209            .text_transform(TextTransform::Uppercase)
1210            .text_transform(TextTransform::Lowercase)
1211            .text_transform(TextTransform::Capitalize)
1212            .build();
1213        
1214        let css_classes = classes.to_css_classes();
1215        
1216        // Font sizes
1217        assert!(css_classes.contains("text-xs"));
1218        assert!(css_classes.contains("text-9xl"));
1219        
1220        // Font weights
1221        assert!(css_classes.contains("font-thin"));
1222        assert!(css_classes.contains("font-black"));
1223        
1224        // Line heights
1225        assert!(css_classes.contains("leading-tight"));
1226        assert!(css_classes.contains("leading-relaxed"));
1227        
1228        // Letter spacing
1229        assert!(css_classes.contains("tracking-tighter"));
1230        assert!(css_classes.contains("tracking-widest"));
1231        
1232        // Text decoration
1233        assert!(css_classes.contains("underline"));
1234        assert!(css_classes.contains("no-underline"));
1235        assert!(css_classes.contains("line-through"));
1236        
1237        // Text transform
1238        assert!(css_classes.contains("uppercase"));
1239        assert!(css_classes.contains("lowercase"));
1240        assert!(css_classes.contains("capitalize"));
1241    }
1242
1243    /// Test extended numeric line height utilities (leading-3 through leading-10)
1244    #[test]
1245    fn test_extended_line_height_utilities() {
1246        let classes = ClassBuilder::new()
1247            .line_height(LineHeight::Three)
1248            .line_height(LineHeight::Four)
1249            .line_height(LineHeight::Five)
1250            .line_height(LineHeight::Six)
1251            .line_height(LineHeight::Seven)
1252            .line_height(LineHeight::Eight)
1253            .line_height(LineHeight::Nine)
1254            .line_height(LineHeight::Ten)
1255            .build();
1256
1257        let css_classes = classes.to_css_classes();
1258        assert!(css_classes.contains("leading-3"));
1259        assert!(css_classes.contains("leading-4"));
1260        assert!(css_classes.contains("leading-5"));
1261        assert!(css_classes.contains("leading-6"));
1262        assert!(css_classes.contains("leading-7"));
1263        assert!(css_classes.contains("leading-8"));
1264        assert!(css_classes.contains("leading-9"));
1265        assert!(css_classes.contains("leading-10"));
1266    }
1267
1268    /// Test extended text decoration utilities
1269    #[test]
1270    fn test_extended_text_decoration_utilities() {
1271        let classes = ClassBuilder::new()
1272            .text_decoration_style(TextDecorationStyle::Solid)
1273            .text_decoration_style(TextDecorationStyle::Double)
1274            .text_decoration_style(TextDecorationStyle::Dotted)
1275            .text_decoration_style(TextDecorationStyle::Dashed)
1276            .text_decoration_style(TextDecorationStyle::Wavy)
1277            .text_decoration_thickness(TextDecorationThickness::Auto)
1278            .text_decoration_thickness(TextDecorationThickness::FromFont)
1279            .text_decoration_thickness(TextDecorationThickness::One)
1280            .text_decoration_thickness(TextDecorationThickness::Two)
1281            .text_decoration_thickness(TextDecorationThickness::Four)
1282            .text_underline_offset(TextUnderlineOffset::Auto)
1283            .text_underline_offset(TextUnderlineOffset::Zero)
1284            .text_underline_offset(TextUnderlineOffset::One)
1285            .text_underline_offset(TextUnderlineOffset::Two)
1286            .text_underline_offset(TextUnderlineOffset::Four)
1287            .build();
1288
1289        let css_classes = classes.to_css_classes();
1290
1291        // Text decoration styles
1292        assert!(css_classes.contains("decoration-solid"));
1293        assert!(css_classes.contains("decoration-double"));
1294        assert!(css_classes.contains("decoration-dotted"));
1295        assert!(css_classes.contains("decoration-dashed"));
1296        assert!(css_classes.contains("decoration-wavy"));
1297
1298        // Text decoration thickness
1299        assert!(css_classes.contains("decoration-auto"));
1300        assert!(css_classes.contains("decoration-from-font"));
1301        assert!(css_classes.contains("decoration-1"));
1302        assert!(css_classes.contains("decoration-2"));
1303        assert!(css_classes.contains("decoration-4"));
1304
1305        // Text underline offset
1306        assert!(css_classes.contains("underline-offset-auto"));
1307        assert!(css_classes.contains("underline-offset-0"));
1308        assert!(css_classes.contains("underline-offset-1"));
1309        assert!(css_classes.contains("underline-offset-2"));
1310        assert!(css_classes.contains("underline-offset-4"));
1311    }
1312
1313    /// Test comprehensive extended typography features
1314    #[test]
1315    fn test_comprehensive_extended_typography() {
1316        let classes = ClassBuilder::new()
1317            // Extended line heights
1318            .line_height(LineHeight::Three)
1319            .line_height(LineHeight::Ten)
1320            // Extended text decorations
1321            .text_decoration(TextDecoration::Underline)
1322            .text_decoration_style(TextDecorationStyle::Wavy)
1323            .text_decoration_thickness(TextDecorationThickness::Two)
1324            .text_underline_offset(TextUnderlineOffset::Four)
1325            // Existing features
1326            .font_size(FontSize::Xl2)
1327            .font_weight(FontWeight::Bold)
1328            .text_transform(TextTransform::Uppercase)
1329            .letter_spacing(LetterSpacing::Wide)
1330            .build();
1331
1332        let css_classes = classes.to_css_classes();
1333
1334        // Extended line heights
1335        assert!(css_classes.contains("leading-3"));
1336        assert!(css_classes.contains("leading-10"));
1337
1338        // Extended text decorations
1339        assert!(css_classes.contains("underline"));
1340        assert!(css_classes.contains("decoration-wavy"));
1341        assert!(css_classes.contains("decoration-2"));
1342        assert!(css_classes.contains("underline-offset-4"));
1343
1344        // Existing features still work
1345        assert!(css_classes.contains("text-2xl"));
1346        assert!(css_classes.contains("font-bold"));
1347        assert!(css_classes.contains("uppercase"));
1348        assert!(css_classes.contains("tracking-wide"));
1349    }
1350
1351    /// Test LineHeight::all_values utility function
1352    #[test]
1353    fn test_line_height_all_values() {
1354        let all_values = LineHeight::all_values();
1355        assert_eq!(all_values.len(), 14); // 8 numeric + 6 named values
1356
1357        // Test that all values are present
1358        assert!(all_values.contains(&LineHeight::None));
1359        assert!(all_values.contains(&LineHeight::Three));
1360        assert!(all_values.contains(&LineHeight::Four));
1361        assert!(all_values.contains(&LineHeight::Five));
1362        assert!(all_values.contains(&LineHeight::Six));
1363        assert!(all_values.contains(&LineHeight::Seven));
1364        assert!(all_values.contains(&LineHeight::Eight));
1365        assert!(all_values.contains(&LineHeight::Nine));
1366        assert!(all_values.contains(&LineHeight::Ten));
1367        assert!(all_values.contains(&LineHeight::Tight));
1368        assert!(all_values.contains(&LineHeight::Snug));
1369        assert!(all_values.contains(&LineHeight::Normal));
1370        assert!(all_values.contains(&LineHeight::Relaxed));
1371        assert!(all_values.contains(&LineHeight::Loose));
1372    }
1373
1374    #[test]
1375    fn test_font_family_display() {
1376        // Test that FontFamily displays correctly
1377        assert_eq!(format!("{}", FontFamily::Sans), "sans");
1378        assert_eq!(format!("{}", FontFamily::Serif), "serif");
1379        assert_eq!(format!("{}", FontFamily::Mono), "mono");
1380    }
1381
1382    #[test]
1383    fn test_font_size_display() {
1384        // Test that FontSize displays correctly
1385        assert_eq!(format!("{}", FontSize::Xs), "xs");
1386        assert_eq!(format!("{}", FontSize::Sm), "sm");
1387        assert_eq!(format!("{}", FontSize::Base), "base");
1388        assert_eq!(format!("{}", FontSize::Lg), "lg");
1389        assert_eq!(format!("{}", FontSize::Xl), "xl");
1390        assert_eq!(format!("{}", FontSize::Xl2), "2xl");
1391        assert_eq!(format!("{}", FontSize::Xl3), "3xl");
1392        assert_eq!(format!("{}", FontSize::Xl4), "4xl");
1393        assert_eq!(format!("{}", FontSize::Xl5), "5xl");
1394        assert_eq!(format!("{}", FontSize::Xl6), "6xl");
1395        assert_eq!(format!("{}", FontSize::Xl7), "7xl");
1396        assert_eq!(format!("{}", FontSize::Xl8), "8xl");
1397        assert_eq!(format!("{}", FontSize::Xl9), "9xl");
1398    }
1399
1400    #[test]
1401    fn test_font_weight_display() {
1402        // Test that FontWeight displays correctly
1403        assert_eq!(format!("{}", FontWeight::Thin), "thin");
1404        assert_eq!(format!("{}", FontWeight::ExtraLight), "extralight");
1405        assert_eq!(format!("{}", FontWeight::Light), "light");
1406        assert_eq!(format!("{}", FontWeight::Normal), "normal");
1407        assert_eq!(format!("{}", FontWeight::Medium), "medium");
1408        assert_eq!(format!("{}", FontWeight::SemiBold), "semibold");
1409        assert_eq!(format!("{}", FontWeight::Bold), "bold");
1410        assert_eq!(format!("{}", FontWeight::ExtraBold), "extrabold");
1411        assert_eq!(format!("{}", FontWeight::Black), "black");
1412    }
1413
1414    #[test]
1415    fn test_text_align_display() {
1416        // Test that TextAlign displays correctly
1417        assert_eq!(format!("{}", TextAlign::Left), "left");
1418        assert_eq!(format!("{}", TextAlign::Center), "center");
1419        assert_eq!(format!("{}", TextAlign::Right), "right");
1420        assert_eq!(format!("{}", TextAlign::Justify), "justify");
1421        assert_eq!(format!("{}", TextAlign::Start), "start");
1422        assert_eq!(format!("{}", TextAlign::End), "end");
1423    }
1424
1425    #[test]
1426    fn test_line_height_display() {
1427        // Test that LineHeight displays correctly
1428        assert_eq!(format!("{}", LineHeight::None), "none");
1429        assert_eq!(format!("{}", LineHeight::Three), "3");
1430        assert_eq!(format!("{}", LineHeight::Four), "4");
1431        assert_eq!(format!("{}", LineHeight::Five), "5");
1432        assert_eq!(format!("{}", LineHeight::Six), "6");
1433        assert_eq!(format!("{}", LineHeight::Seven), "7");
1434        assert_eq!(format!("{}", LineHeight::Eight), "8");
1435        assert_eq!(format!("{}", LineHeight::Nine), "9");
1436        assert_eq!(format!("{}", LineHeight::Ten), "10");
1437        assert_eq!(format!("{}", LineHeight::Tight), "tight");
1438        assert_eq!(format!("{}", LineHeight::Snug), "snug");
1439        assert_eq!(format!("{}", LineHeight::Normal), "normal");
1440        assert_eq!(format!("{}", LineHeight::Relaxed), "relaxed");
1441        assert_eq!(format!("{}", LineHeight::Loose), "loose");
1442        assert_eq!(format!("{}", LineHeight::Custom(1.5)), "1.5");
1443    }
1444
1445    #[test]
1446    fn test_letter_spacing_display() {
1447        // Test that LetterSpacing displays correctly
1448        assert_eq!(format!("{}", LetterSpacing::Tighter), "tighter");
1449        assert_eq!(format!("{}", LetterSpacing::Tight), "tight");
1450        assert_eq!(format!("{}", LetterSpacing::Normal), "normal");
1451        assert_eq!(format!("{}", LetterSpacing::Wide), "wide");
1452        assert_eq!(format!("{}", LetterSpacing::Wider), "wider");
1453        assert_eq!(format!("{}", LetterSpacing::Widest), "widest");
1454        assert_eq!(format!("{}", LetterSpacing::Custom(0.1)), "0.1");
1455    }
1456
1457    #[test]
1458    fn test_text_decoration_display() {
1459        // Test that TextDecoration displays correctly
1460        assert_eq!(format!("{}", TextDecoration::None), "no-underline");
1461        assert_eq!(format!("{}", TextDecoration::Underline), "underline");
1462        assert_eq!(format!("{}", TextDecoration::Overline), "overline");
1463        assert_eq!(format!("{}", TextDecoration::LineThrough), "line-through");
1464    }
1465
1466    #[test]
1467    fn test_text_transform_display() {
1468        // Test that TextTransform displays correctly
1469        assert_eq!(format!("{}", TextTransform::None), "normal-case");
1470        assert_eq!(format!("{}", TextTransform::Uppercase), "uppercase");
1471        assert_eq!(format!("{}", TextTransform::Lowercase), "lowercase");
1472        assert_eq!(format!("{}", TextTransform::Capitalize), "capitalize");
1473    }
1474
1475    #[test]
1476    fn test_text_overflow_class_names() {
1477        // Test that TextOverflow generates correct class names
1478        assert_eq!(TextOverflow::Truncate.to_class_name(), "truncate");
1479        assert_eq!(TextOverflow::Ellipsis.to_class_name(), "text-ellipsis");
1480        assert_eq!(TextOverflow::Clip.to_class_name(), "text-clip");
1481    }
1482
1483    #[test]
1484    fn test_white_space_class_names() {
1485        // Test that WhiteSpace generates correct class names
1486        assert_eq!(WhiteSpace::Normal.to_class_name(), "whitespace-normal");
1487        assert_eq!(WhiteSpace::Nowrap.to_class_name(), "whitespace-nowrap");
1488        assert_eq!(WhiteSpace::Pre.to_class_name(), "whitespace-pre");
1489        assert_eq!(WhiteSpace::PreLine.to_class_name(), "whitespace-pre-line");
1490        assert_eq!(WhiteSpace::PreWrap.to_class_name(), "whitespace-pre-wrap");
1491        assert_eq!(WhiteSpace::BreakSpaces.to_class_name(), "whitespace-break-spaces");
1492    }
1493
1494    #[test]
1495    fn test_word_break_class_names() {
1496        // Test that WordBreak generates correct class names
1497        assert_eq!(WordBreak::Normal.to_class_name(), "break-normal");
1498        assert_eq!(WordBreak::BreakAll.to_class_name(), "break-all");
1499        assert_eq!(WordBreak::BreakWords.to_class_name(), "break-words");
1500        assert_eq!(WordBreak::KeepAll.to_class_name(), "break-keep");
1501    }
1502
1503    #[test]
1504    fn test_font_family_css_values() {
1505        // Test that FontFamily generates correct CSS values
1506        assert_eq!(FontFamily::Sans.to_css_value(), "ui-sans-serif, system-ui, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\"");
1507        assert_eq!(FontFamily::Serif.to_css_value(), "ui-serif, Georgia, Cambria, \"Times New Roman\", Times, serif");
1508        assert_eq!(FontFamily::Mono.to_css_value(), "ui-monospace, SFMono-Regular, \"SF Mono\", Consolas, \"Liberation Mono\", Menlo, monospace");
1509    }
1510
1511    #[test]
1512    fn test_font_size_css_values() {
1513        // Test that FontSize generates correct CSS values
1514        assert_eq!(FontSize::Xs.to_css_value(), "0.75rem");
1515        assert_eq!(FontSize::Sm.to_css_value(), "0.875rem");
1516        assert_eq!(FontSize::Base.to_css_value(), "1rem");
1517        assert_eq!(FontSize::Lg.to_css_value(), "1.125rem");
1518        assert_eq!(FontSize::Xl.to_css_value(), "1.25rem");
1519        assert_eq!(FontSize::Xl2.to_css_value(), "1.5rem");
1520        assert_eq!(FontSize::Xl3.to_css_value(), "1.875rem");
1521        assert_eq!(FontSize::Xl4.to_css_value(), "2.25rem");
1522        assert_eq!(FontSize::Xl5.to_css_value(), "3rem");
1523        assert_eq!(FontSize::Xl6.to_css_value(), "3.75rem");
1524        assert_eq!(FontSize::Xl7.to_css_value(), "4.5rem");
1525        assert_eq!(FontSize::Xl8.to_css_value(), "6rem");
1526        assert_eq!(FontSize::Xl9.to_css_value(), "8rem");
1527    }
1528
1529    #[test]
1530    fn test_font_weight_css_values() {
1531        // Test that FontWeight generates correct CSS values
1532        assert_eq!(FontWeight::Thin.to_css_value(), "100");
1533        assert_eq!(FontWeight::ExtraLight.to_css_value(), "200");
1534        assert_eq!(FontWeight::Light.to_css_value(), "300");
1535        assert_eq!(FontWeight::Normal.to_css_value(), "400");
1536        assert_eq!(FontWeight::Medium.to_css_value(), "500");
1537        assert_eq!(FontWeight::SemiBold.to_css_value(), "600");
1538        assert_eq!(FontWeight::Bold.to_css_value(), "700");
1539        assert_eq!(FontWeight::ExtraBold.to_css_value(), "800");
1540        assert_eq!(FontWeight::Black.to_css_value(), "900");
1541    }
1542
1543    #[test]
1544    fn test_text_align_css_values() {
1545        // Test that TextAlign generates correct CSS values
1546        assert_eq!(TextAlign::Left.to_css_value(), "left");
1547        assert_eq!(TextAlign::Center.to_css_value(), "center");
1548        assert_eq!(TextAlign::Right.to_css_value(), "right");
1549        assert_eq!(TextAlign::Justify.to_css_value(), "justify");
1550        assert_eq!(TextAlign::Start.to_css_value(), "start");
1551        assert_eq!(TextAlign::End.to_css_value(), "end");
1552    }
1553
1554    #[test]
1555    fn test_line_height_css_values() {
1556        // Test that LineHeight generates correct CSS values
1557        assert_eq!(LineHeight::None.to_css_value(), "1");
1558        assert_eq!(LineHeight::Three.to_css_value(), "0.75rem");
1559        assert_eq!(LineHeight::Four.to_css_value(), "1rem");
1560        assert_eq!(LineHeight::Five.to_css_value(), "1.25rem");
1561        assert_eq!(LineHeight::Six.to_css_value(), "1.5rem");
1562        assert_eq!(LineHeight::Seven.to_css_value(), "1.75rem");
1563        assert_eq!(LineHeight::Eight.to_css_value(), "2rem");
1564        assert_eq!(LineHeight::Nine.to_css_value(), "2.25rem");
1565        assert_eq!(LineHeight::Ten.to_css_value(), "2.5rem");
1566        assert_eq!(LineHeight::Tight.to_css_value(), "1.25");
1567        assert_eq!(LineHeight::Snug.to_css_value(), "1.375");
1568        assert_eq!(LineHeight::Normal.to_css_value(), "1.5");
1569        assert_eq!(LineHeight::Relaxed.to_css_value(), "1.625");
1570        assert_eq!(LineHeight::Loose.to_css_value(), "2");
1571        assert_eq!(LineHeight::Custom(1.5).to_css_value(), "1.5");
1572    }
1573
1574    #[test]
1575    fn test_letter_spacing_css_values() {
1576        // Test that LetterSpacing generates correct CSS values
1577        assert_eq!(LetterSpacing::Tighter.to_css_value(), "-0.05em");
1578        assert_eq!(LetterSpacing::Tight.to_css_value(), "-0.025em");
1579        assert_eq!(LetterSpacing::Normal.to_css_value(), "0em");
1580        assert_eq!(LetterSpacing::Wide.to_css_value(), "0.025em");
1581        assert_eq!(LetterSpacing::Wider.to_css_value(), "0.05em");
1582        assert_eq!(LetterSpacing::Widest.to_css_value(), "0.1em");
1583        assert_eq!(LetterSpacing::Custom(0.1).to_css_value(), "0.1em");
1584    }
1585
1586    #[test]
1587    fn test_typography_serialization() {
1588        // Test that typography enums can be serialized and deserialized
1589        let font_family = FontFamily::Sans;
1590        let serialized = serde_json::to_string(&font_family).unwrap();
1591        let deserialized: FontFamily = serde_json::from_str(&serialized).unwrap();
1592        assert_eq!(font_family, deserialized);
1593
1594        let font_size = FontSize::Lg;
1595        let serialized = serde_json::to_string(&font_size).unwrap();
1596        let deserialized: FontSize = serde_json::from_str(&serialized).unwrap();
1597        assert_eq!(font_size, deserialized);
1598
1599        let font_weight = FontWeight::Bold;
1600        let serialized = serde_json::to_string(&font_weight).unwrap();
1601        let deserialized: FontWeight = serde_json::from_str(&serialized).unwrap();
1602        assert_eq!(font_weight, deserialized);
1603
1604        let text_align = TextAlign::Center;
1605        let serialized = serde_json::to_string(&text_align).unwrap();
1606        let deserialized: TextAlign = serde_json::from_str(&serialized).unwrap();
1607        assert_eq!(text_align, deserialized);
1608
1609        let line_height = LineHeight::Relaxed;
1610        let serialized = serde_json::to_string(&line_height).unwrap();
1611        let deserialized: LineHeight = serde_json::from_str(&serialized).unwrap();
1612        assert_eq!(line_height, deserialized);
1613
1614        let letter_spacing = LetterSpacing::Wide;
1615        let serialized = serde_json::to_string(&letter_spacing).unwrap();
1616        let deserialized: LetterSpacing = serde_json::from_str(&serialized).unwrap();
1617        assert_eq!(letter_spacing, deserialized);
1618    }
1619
1620    #[test]
1621    fn test_typography_equality_and_hash() {
1622        // Test that typography enums can be compared for equality and hashed
1623        let font_family1 = FontFamily::Sans;
1624        let font_family2 = FontFamily::Sans;
1625        let font_family3 = FontFamily::Serif;
1626        
1627        assert_eq!(font_family1, font_family2);
1628        assert_ne!(font_family1, font_family3);
1629        
1630        // Test that equal enums have the same hash
1631        use std::collections::hash_map::DefaultHasher;
1632        use std::hash::{Hash, Hasher};
1633        
1634        let mut hasher1 = DefaultHasher::new();
1635        let mut hasher2 = DefaultHasher::new();
1636        font_family1.hash(&mut hasher1);
1637        font_family2.hash(&mut hasher2);
1638        assert_eq!(hasher1.finish(), hasher2.finish());
1639    }
1640
1641    #[test]
1642    fn test_comprehensive_typography_utilities() {
1643        // Test comprehensive usage of all typography utility methods
1644        let classes = ClassBuilder::new()
1645            // Font families
1646            .font_family(FontFamily::Sans)
1647            .font_family(FontFamily::Serif)
1648            .font_family(FontFamily::Mono)
1649            
1650            // Font sizes
1651            .font_size(FontSize::Xs)
1652            .font_size(FontSize::Sm)
1653            .font_size(FontSize::Base)
1654            .font_size(FontSize::Lg)
1655            .font_size(FontSize::Xl)
1656            .font_size(FontSize::Xl2)
1657            .font_size(FontSize::Xl3)
1658            .font_size(FontSize::Xl4)
1659            .font_size(FontSize::Xl5)
1660            .font_size(FontSize::Xl6)
1661            .font_size(FontSize::Xl7)
1662            .font_size(FontSize::Xl8)
1663            .font_size(FontSize::Xl9)
1664            
1665            // Font weights
1666            .font_weight(FontWeight::Thin)
1667            .font_weight(FontWeight::ExtraLight)
1668            .font_weight(FontWeight::Light)
1669            .font_weight(FontWeight::Normal)
1670            .font_weight(FontWeight::Medium)
1671            .font_weight(FontWeight::SemiBold)
1672            .font_weight(FontWeight::Bold)
1673            .font_weight(FontWeight::ExtraBold)
1674            .font_weight(FontWeight::Black)
1675            
1676            // Text alignment
1677            .text_align(TextAlign::Left)
1678            .text_align(TextAlign::Center)
1679            .text_align(TextAlign::Right)
1680            .text_align(TextAlign::Justify)
1681            .text_align(TextAlign::Start)
1682            .text_align(TextAlign::End)
1683            
1684            // Line heights
1685            .line_height(LineHeight::None)
1686            .line_height(LineHeight::Three)
1687            .line_height(LineHeight::Four)
1688            .line_height(LineHeight::Five)
1689            .line_height(LineHeight::Six)
1690            .line_height(LineHeight::Seven)
1691            .line_height(LineHeight::Eight)
1692            .line_height(LineHeight::Nine)
1693            .line_height(LineHeight::Ten)
1694            .line_height(LineHeight::Tight)
1695            .line_height(LineHeight::Snug)
1696            .line_height(LineHeight::Normal)
1697            .line_height(LineHeight::Relaxed)
1698            .line_height(LineHeight::Loose)
1699            .line_height(LineHeight::Custom(1.5))
1700            
1701            // Letter spacing
1702            .letter_spacing(LetterSpacing::Tighter)
1703            .letter_spacing(LetterSpacing::Tight)
1704            .letter_spacing(LetterSpacing::Normal)
1705            .letter_spacing(LetterSpacing::Wide)
1706            .letter_spacing(LetterSpacing::Wider)
1707            .letter_spacing(LetterSpacing::Widest)
1708            .letter_spacing(LetterSpacing::Custom(0.1))
1709            
1710            // Text decoration
1711            .text_decoration(TextDecoration::None)
1712            .text_decoration(TextDecoration::Underline)
1713            .text_decoration(TextDecoration::Overline)
1714            .text_decoration(TextDecoration::LineThrough)
1715            
1716            // Text transform
1717            .text_transform(TextTransform::None)
1718            .text_transform(TextTransform::Uppercase)
1719            .text_transform(TextTransform::Lowercase)
1720            .text_transform(TextTransform::Capitalize)
1721            
1722            // Text overflow
1723            .text_overflow(TextOverflow::Truncate)
1724            .text_overflow(TextOverflow::Ellipsis)
1725            .text_overflow(TextOverflow::Clip)
1726            
1727            // White space
1728            .white_space(WhiteSpace::Normal)
1729            .white_space(WhiteSpace::Nowrap)
1730            .white_space(WhiteSpace::Pre)
1731            .white_space(WhiteSpace::PreLine)
1732            .white_space(WhiteSpace::PreWrap)
1733            .white_space(WhiteSpace::BreakSpaces)
1734            
1735            // Word break
1736            .word_break(WordBreak::Normal)
1737            .word_break(WordBreak::BreakAll)
1738            .word_break(WordBreak::BreakWords)
1739            .word_break(WordBreak::KeepAll)
1740            
1741            // Text decoration style
1742            .text_decoration_style(TextDecorationStyle::Solid)
1743            .text_decoration_style(TextDecorationStyle::Double)
1744            .text_decoration_style(TextDecorationStyle::Dotted)
1745            .text_decoration_style(TextDecorationStyle::Dashed)
1746            .text_decoration_style(TextDecorationStyle::Wavy)
1747            
1748            // Text decoration thickness
1749            .text_decoration_thickness(TextDecorationThickness::Auto)
1750            .text_decoration_thickness(TextDecorationThickness::FromFont)
1751            .text_decoration_thickness(TextDecorationThickness::Zero)
1752            .text_decoration_thickness(TextDecorationThickness::One)
1753            .text_decoration_thickness(TextDecorationThickness::Two)
1754            .text_decoration_thickness(TextDecorationThickness::Four)
1755            .text_decoration_thickness(TextDecorationThickness::Eight)
1756            
1757            // Text underline offset
1758            .text_underline_offset(TextUnderlineOffset::Auto)
1759            .text_underline_offset(TextUnderlineOffset::Zero)
1760            .text_underline_offset(TextUnderlineOffset::One)
1761            .text_underline_offset(TextUnderlineOffset::Two)
1762            .text_underline_offset(TextUnderlineOffset::Four)
1763            .text_underline_offset(TextUnderlineOffset::Eight)
1764            .build();
1765        
1766        let css_classes = classes.to_css_classes();
1767        
1768        // Verify font families
1769        assert!(css_classes.contains("font-sans"));
1770        assert!(css_classes.contains("font-serif"));
1771        assert!(css_classes.contains("font-mono"));
1772        
1773        // Verify font sizes
1774        assert!(css_classes.contains("text-xs"));
1775        assert!(css_classes.contains("text-sm"));
1776        assert!(css_classes.contains("text-base"));
1777        assert!(css_classes.contains("text-lg"));
1778        assert!(css_classes.contains("text-xl"));
1779        assert!(css_classes.contains("text-2xl"));
1780        assert!(css_classes.contains("text-3xl"));
1781        assert!(css_classes.contains("text-4xl"));
1782        assert!(css_classes.contains("text-5xl"));
1783        assert!(css_classes.contains("text-6xl"));
1784        assert!(css_classes.contains("text-7xl"));
1785        assert!(css_classes.contains("text-8xl"));
1786        assert!(css_classes.contains("text-9xl"));
1787        
1788        // Verify font weights
1789        assert!(css_classes.contains("font-thin"));
1790        assert!(css_classes.contains("font-extralight"));
1791        assert!(css_classes.contains("font-light"));
1792        assert!(css_classes.contains("font-normal"));
1793        assert!(css_classes.contains("font-medium"));
1794        assert!(css_classes.contains("font-semibold"));
1795        assert!(css_classes.contains("font-bold"));
1796        assert!(css_classes.contains("font-extrabold"));
1797        assert!(css_classes.contains("font-black"));
1798        
1799        // Verify text alignment
1800        assert!(css_classes.contains("text-left"));
1801        assert!(css_classes.contains("text-center"));
1802        assert!(css_classes.contains("text-right"));
1803        assert!(css_classes.contains("text-justify"));
1804        assert!(css_classes.contains("text-start"));
1805        assert!(css_classes.contains("text-end"));
1806        
1807        // Verify line heights
1808        assert!(css_classes.contains("leading-none"));
1809        assert!(css_classes.contains("leading-3"));
1810        assert!(css_classes.contains("leading-4"));
1811        assert!(css_classes.contains("leading-5"));
1812        assert!(css_classes.contains("leading-6"));
1813        assert!(css_classes.contains("leading-7"));
1814        assert!(css_classes.contains("leading-8"));
1815        assert!(css_classes.contains("leading-9"));
1816        assert!(css_classes.contains("leading-10"));
1817        assert!(css_classes.contains("leading-tight"));
1818        assert!(css_classes.contains("leading-snug"));
1819        assert!(css_classes.contains("leading-normal"));
1820        assert!(css_classes.contains("leading-relaxed"));
1821        assert!(css_classes.contains("leading-loose"));
1822        assert!(css_classes.contains("leading-1.5"));
1823        
1824        // Verify letter spacing
1825        assert!(css_classes.contains("tracking-tighter"));
1826        assert!(css_classes.contains("tracking-tight"));
1827        assert!(css_classes.contains("tracking-normal"));
1828        assert!(css_classes.contains("tracking-wide"));
1829        assert!(css_classes.contains("tracking-wider"));
1830        assert!(css_classes.contains("tracking-widest"));
1831        assert!(css_classes.contains("tracking-0.1"));
1832        
1833        // Verify text decoration
1834        assert!(css_classes.contains("no-underline"));
1835        assert!(css_classes.contains("underline"));
1836        assert!(css_classes.contains("overline"));
1837        assert!(css_classes.contains("line-through"));
1838        
1839        // Verify text transform
1840        assert!(css_classes.contains("normal-case"));
1841        assert!(css_classes.contains("uppercase"));
1842        assert!(css_classes.contains("lowercase"));
1843        assert!(css_classes.contains("capitalize"));
1844        
1845        // Verify text overflow
1846        assert!(css_classes.contains("truncate"));
1847        assert!(css_classes.contains("text-ellipsis"));
1848        assert!(css_classes.contains("text-clip"));
1849        
1850        // Verify white space
1851        assert!(css_classes.contains("whitespace-normal"));
1852        assert!(css_classes.contains("whitespace-nowrap"));
1853        assert!(css_classes.contains("whitespace-pre"));
1854        assert!(css_classes.contains("whitespace-pre-line"));
1855        assert!(css_classes.contains("whitespace-pre-wrap"));
1856        assert!(css_classes.contains("whitespace-break-spaces"));
1857        
1858        // Verify word break
1859        assert!(css_classes.contains("break-normal"));
1860        assert!(css_classes.contains("break-all"));
1861        assert!(css_classes.contains("break-words"));
1862        assert!(css_classes.contains("break-keep"));
1863        
1864        // Verify text decoration style
1865        assert!(css_classes.contains("decoration-solid"));
1866        assert!(css_classes.contains("decoration-double"));
1867        assert!(css_classes.contains("decoration-dotted"));
1868        assert!(css_classes.contains("decoration-dashed"));
1869        assert!(css_classes.contains("decoration-wavy"));
1870        
1871        // Verify text decoration thickness
1872        assert!(css_classes.contains("decoration-auto"));
1873        assert!(css_classes.contains("decoration-from-font"));
1874        assert!(css_classes.contains("decoration-0"));
1875        assert!(css_classes.contains("decoration-1"));
1876        assert!(css_classes.contains("decoration-2"));
1877        assert!(css_classes.contains("decoration-4"));
1878        assert!(css_classes.contains("decoration-8"));
1879        
1880        // Verify text underline offset
1881        assert!(css_classes.contains("underline-offset-auto"));
1882        assert!(css_classes.contains("underline-offset-0"));
1883        assert!(css_classes.contains("underline-offset-1"));
1884        assert!(css_classes.contains("underline-offset-2"));
1885        assert!(css_classes.contains("underline-offset-4"));
1886        assert!(css_classes.contains("underline-offset-8"));
1887    }
1888}