1use crate::classes::ClassBuilder;
7use serde::{Deserialize, Serialize};
8use std::fmt;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
12pub enum FontFamily {
13 Sans,
15 Serif,
17 Mono,
19}
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
23pub enum FontSize {
24 Xs,
26 Sm,
28 Base,
30 Lg,
32 Xl,
34 Xl2,
36 Xl3,
38 Xl4,
40 Xl5,
42 Xl6,
44 Xl7,
46 Xl8,
48 Xl9,
50}
51
52#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
54pub enum FontWeight {
55 Thin,
57 ExtraLight,
59 Light,
61 Normal,
63 Medium,
65 SemiBold,
67 Bold,
69 ExtraBold,
71 Black,
73}
74
75#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
77pub enum TextAlign {
78 Left,
80 Center,
82 Right,
84 Justify,
86 Start,
88 End,
90}
91
92#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
94pub enum LineHeight {
95 None,
97 Tight,
99 Snug,
101 Normal,
103 Relaxed,
105 Loose,
107 Custom(f32),
109}
110
111#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
113pub enum LetterSpacing {
114 Tighter,
116 Tight,
118 Normal,
120 Wide,
122 Wider,
124 Widest,
126 Custom(f32),
128}
129
130#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
132pub enum TextDecoration {
133 None,
135 Underline,
137 Overline,
139 LineThrough,
141}
142
143#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
145pub enum TextTransform {
146 None,
148 Uppercase,
150 Lowercase,
152 Capitalize,
154}
155
156#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
158pub enum TextOverflow {
159 Truncate,
161 Ellipsis,
163 Clip,
165}
166
167#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
169pub enum WhiteSpace {
170 Normal,
172 Nowrap,
174 Pre,
176 PreLine,
178 PreWrap,
180 BreakSpaces,
182}
183
184#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
186pub enum WordBreak {
187 Normal,
189 BreakAll,
191 BreakWords,
193 KeepAll,
195}
196
197impl std::hash::Hash for LineHeight {
198 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
199 match self {
200 LineHeight::None => 0u8.hash(state),
201 LineHeight::Tight => 1u8.hash(state),
202 LineHeight::Snug => 2u8.hash(state),
203 LineHeight::Normal => 3u8.hash(state),
204 LineHeight::Relaxed => 4u8.hash(state),
205 LineHeight::Loose => 5u8.hash(state),
206 LineHeight::Custom(f) => {
207 6u8.hash(state);
208 ((f * 1000.0) as u32).hash(state);
209 }
210 }
211 }
212}
213
214impl std::hash::Hash for LetterSpacing {
215 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
216 match self {
217 LetterSpacing::Tighter => 0u8.hash(state),
218 LetterSpacing::Tight => 1u8.hash(state),
219 LetterSpacing::Normal => 2u8.hash(state),
220 LetterSpacing::Wide => 3u8.hash(state),
221 LetterSpacing::Wider => 4u8.hash(state),
222 LetterSpacing::Widest => 5u8.hash(state),
223 LetterSpacing::Custom(f) => {
224 6u8.hash(state);
225 ((f * 1000.0) as u32).hash(state);
226 }
227 }
228 }
229}
230
231impl std::cmp::Eq for LineHeight {}
232impl std::cmp::Eq for LetterSpacing {}
233
234impl FontFamily {
235 pub fn to_class_name(&self) -> String {
236 match self {
237 FontFamily::Sans => "sans".to_string(),
238 FontFamily::Serif => "serif".to_string(),
239 FontFamily::Mono => "mono".to_string(),
240 }
241 }
242
243 pub fn to_css_value(&self) -> String {
244 match self {
245 FontFamily::Sans => "ui-sans-serif, system-ui, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\"".to_string(),
246 FontFamily::Serif => "ui-serif, Georgia, Cambria, \"Times New Roman\", Times, serif".to_string(),
247 FontFamily::Mono => "ui-monospace, SFMono-Regular, \"SF Mono\", Consolas, \"Liberation Mono\", Menlo, monospace".to_string(),
248 }
249 }
250}
251
252impl FontSize {
253 pub fn to_class_name(&self) -> String {
254 match self {
255 FontSize::Xs => "xs".to_string(),
256 FontSize::Sm => "sm".to_string(),
257 FontSize::Base => "base".to_string(),
258 FontSize::Lg => "lg".to_string(),
259 FontSize::Xl => "xl".to_string(),
260 FontSize::Xl2 => "2xl".to_string(),
261 FontSize::Xl3 => "3xl".to_string(),
262 FontSize::Xl4 => "4xl".to_string(),
263 FontSize::Xl5 => "5xl".to_string(),
264 FontSize::Xl6 => "6xl".to_string(),
265 FontSize::Xl7 => "7xl".to_string(),
266 FontSize::Xl8 => "8xl".to_string(),
267 FontSize::Xl9 => "9xl".to_string(),
268 }
269 }
270
271 pub fn to_css_value(&self) -> String {
272 match self {
273 FontSize::Xs => "0.75rem".to_string(),
274 FontSize::Sm => "0.875rem".to_string(),
275 FontSize::Base => "1rem".to_string(),
276 FontSize::Lg => "1.125rem".to_string(),
277 FontSize::Xl => "1.25rem".to_string(),
278 FontSize::Xl2 => "1.5rem".to_string(),
279 FontSize::Xl3 => "1.875rem".to_string(),
280 FontSize::Xl4 => "2.25rem".to_string(),
281 FontSize::Xl5 => "3rem".to_string(),
282 FontSize::Xl6 => "3.75rem".to_string(),
283 FontSize::Xl7 => "4.5rem".to_string(),
284 FontSize::Xl8 => "6rem".to_string(),
285 FontSize::Xl9 => "8rem".to_string(),
286 }
287 }
288}
289
290impl FontWeight {
291 pub fn to_class_name(&self) -> String {
292 match self {
293 FontWeight::Thin => "thin".to_string(),
294 FontWeight::ExtraLight => "extralight".to_string(),
295 FontWeight::Light => "light".to_string(),
296 FontWeight::Normal => "normal".to_string(),
297 FontWeight::Medium => "medium".to_string(),
298 FontWeight::SemiBold => "semibold".to_string(),
299 FontWeight::Bold => "bold".to_string(),
300 FontWeight::ExtraBold => "extrabold".to_string(),
301 FontWeight::Black => "black".to_string(),
302 }
303 }
304
305 pub fn to_css_value(&self) -> String {
306 match self {
307 FontWeight::Thin => "100".to_string(),
308 FontWeight::ExtraLight => "200".to_string(),
309 FontWeight::Light => "300".to_string(),
310 FontWeight::Normal => "400".to_string(),
311 FontWeight::Medium => "500".to_string(),
312 FontWeight::SemiBold => "600".to_string(),
313 FontWeight::Bold => "700".to_string(),
314 FontWeight::ExtraBold => "800".to_string(),
315 FontWeight::Black => "900".to_string(),
316 }
317 }
318}
319
320impl TextAlign {
321 pub fn to_class_name(&self) -> String {
322 match self {
323 TextAlign::Left => "left".to_string(),
324 TextAlign::Center => "center".to_string(),
325 TextAlign::Right => "right".to_string(),
326 TextAlign::Justify => "justify".to_string(),
327 TextAlign::Start => "start".to_string(),
328 TextAlign::End => "end".to_string(),
329 }
330 }
331
332 pub fn to_css_value(&self) -> String {
333 match self {
334 TextAlign::Left => "left".to_string(),
335 TextAlign::Center => "center".to_string(),
336 TextAlign::Right => "right".to_string(),
337 TextAlign::Justify => "justify".to_string(),
338 TextAlign::Start => "start".to_string(),
339 TextAlign::End => "end".to_string(),
340 }
341 }
342}
343
344impl LineHeight {
345 pub fn to_class_name(&self) -> String {
346 match self {
347 LineHeight::None => "none".to_string(),
348 LineHeight::Tight => "tight".to_string(),
349 LineHeight::Snug => "snug".to_string(),
350 LineHeight::Normal => "normal".to_string(),
351 LineHeight::Relaxed => "relaxed".to_string(),
352 LineHeight::Loose => "loose".to_string(),
353 LineHeight::Custom(f) => format!("{}", f),
354 }
355 }
356
357 pub fn to_css_value(&self) -> String {
358 match self {
359 LineHeight::None => "1".to_string(),
360 LineHeight::Tight => "1.25".to_string(),
361 LineHeight::Snug => "1.375".to_string(),
362 LineHeight::Normal => "1.5".to_string(),
363 LineHeight::Relaxed => "1.625".to_string(),
364 LineHeight::Loose => "2".to_string(),
365 LineHeight::Custom(f) => f.to_string(),
366 }
367 }
368}
369
370impl LetterSpacing {
371 pub fn to_class_name(&self) -> String {
372 match self {
373 LetterSpacing::Tighter => "tighter".to_string(),
374 LetterSpacing::Tight => "tight".to_string(),
375 LetterSpacing::Normal => "normal".to_string(),
376 LetterSpacing::Wide => "wide".to_string(),
377 LetterSpacing::Wider => "wider".to_string(),
378 LetterSpacing::Widest => "widest".to_string(),
379 LetterSpacing::Custom(f) => format!("{}", f),
380 }
381 }
382
383 pub fn to_css_value(&self) -> String {
384 match self {
385 LetterSpacing::Tighter => "-0.05em".to_string(),
386 LetterSpacing::Tight => "-0.025em".to_string(),
387 LetterSpacing::Normal => "0em".to_string(),
388 LetterSpacing::Wide => "0.025em".to_string(),
389 LetterSpacing::Wider => "0.05em".to_string(),
390 LetterSpacing::Widest => "0.1em".to_string(),
391 LetterSpacing::Custom(f) => format!("{}em", f),
392 }
393 }
394}
395
396impl TextDecoration {
397 pub fn to_class_name(&self) -> String {
398 match self {
399 TextDecoration::None => "no-underline".to_string(),
400 TextDecoration::Underline => "underline".to_string(),
401 TextDecoration::Overline => "overline".to_string(),
402 TextDecoration::LineThrough => "line-through".to_string(),
403 }
404 }
405
406 pub fn to_css_value(&self) -> String {
407 match self {
408 TextDecoration::None => "none".to_string(),
409 TextDecoration::Underline => "underline".to_string(),
410 TextDecoration::Overline => "overline".to_string(),
411 TextDecoration::LineThrough => "line-through".to_string(),
412 }
413 }
414}
415
416impl TextTransform {
417 pub fn to_class_name(&self) -> String {
418 match self {
419 TextTransform::None => "normal-case".to_string(),
420 TextTransform::Uppercase => "uppercase".to_string(),
421 TextTransform::Lowercase => "lowercase".to_string(),
422 TextTransform::Capitalize => "capitalize".to_string(),
423 }
424 }
425
426 pub fn to_css_value(&self) -> String {
427 match self {
428 TextTransform::None => "none".to_string(),
429 TextTransform::Uppercase => "uppercase".to_string(),
430 TextTransform::Lowercase => "lowercase".to_string(),
431 TextTransform::Capitalize => "capitalize".to_string(),
432 }
433 }
434}
435
436impl TextOverflow {
437 pub fn to_class_name(&self) -> String {
438 match self {
439 TextOverflow::Truncate => "truncate".to_string(),
440 TextOverflow::Ellipsis => "text-ellipsis".to_string(),
441 TextOverflow::Clip => "text-clip".to_string(),
442 }
443 }
444
445 pub fn to_css_value(&self) -> String {
446 match self {
447 TextOverflow::Truncate => "truncate".to_string(),
448 TextOverflow::Ellipsis => "ellipsis".to_string(),
449 TextOverflow::Clip => "clip".to_string(),
450 }
451 }
452}
453
454impl WhiteSpace {
455 pub fn to_class_name(&self) -> String {
456 match self {
457 WhiteSpace::Normal => "whitespace-normal".to_string(),
458 WhiteSpace::Nowrap => "whitespace-nowrap".to_string(),
459 WhiteSpace::Pre => "whitespace-pre".to_string(),
460 WhiteSpace::PreLine => "whitespace-pre-line".to_string(),
461 WhiteSpace::PreWrap => "whitespace-pre-wrap".to_string(),
462 WhiteSpace::BreakSpaces => "whitespace-break-spaces".to_string(),
463 }
464 }
465
466 pub fn to_css_value(&self) -> String {
467 match self {
468 WhiteSpace::Normal => "normal".to_string(),
469 WhiteSpace::Nowrap => "nowrap".to_string(),
470 WhiteSpace::Pre => "pre".to_string(),
471 WhiteSpace::PreLine => "pre-line".to_string(),
472 WhiteSpace::PreWrap => "pre-wrap".to_string(),
473 WhiteSpace::BreakSpaces => "break-spaces".to_string(),
474 }
475 }
476}
477
478impl WordBreak {
479 pub fn to_class_name(&self) -> String {
480 match self {
481 WordBreak::Normal => "break-normal".to_string(),
482 WordBreak::BreakAll => "break-all".to_string(),
483 WordBreak::BreakWords => "break-words".to_string(),
484 WordBreak::KeepAll => "break-keep".to_string(),
485 }
486 }
487
488 pub fn to_css_value(&self) -> String {
489 match self {
490 WordBreak::Normal => "normal".to_string(),
491 WordBreak::BreakAll => "break-all".to_string(),
492 WordBreak::BreakWords => "break-words".to_string(),
493 WordBreak::KeepAll => "keep-all".to_string(),
494 }
495 }
496}
497
498impl fmt::Display for FontFamily {
499 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
500 write!(f, "{}", self.to_class_name())
501 }
502}
503
504impl fmt::Display for FontSize {
505 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
506 write!(f, "{}", self.to_class_name())
507 }
508}
509
510impl fmt::Display for FontWeight {
511 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
512 write!(f, "{}", self.to_class_name())
513 }
514}
515
516impl fmt::Display for TextAlign {
517 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
518 write!(f, "{}", self.to_class_name())
519 }
520}
521
522impl fmt::Display for LineHeight {
523 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
524 write!(f, "{}", self.to_class_name())
525 }
526}
527
528impl fmt::Display for LetterSpacing {
529 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
530 write!(f, "{}", self.to_class_name())
531 }
532}
533
534pub trait FontFamilyUtilities {
536 fn font_family(self, family: FontFamily) -> Self;
538}
539
540impl FontFamilyUtilities for ClassBuilder {
541 fn font_family(self, family: FontFamily) -> Self {
542 self.class(format!("font-{}", family.to_class_name()))
543 }
544}
545
546pub trait FontSizeUtilities {
548 fn font_size(self, size: FontSize) -> Self;
550}
551
552impl FontSizeUtilities for ClassBuilder {
553 fn font_size(self, size: FontSize) -> Self {
554 self.class(format!("text-{}", size.to_class_name()))
555 }
556}
557
558pub trait FontWeightUtilities {
560 fn font_weight(self, weight: FontWeight) -> Self;
562}
563
564impl FontWeightUtilities for ClassBuilder {
565 fn font_weight(self, weight: FontWeight) -> Self {
566 self.class(format!("font-{}", weight.to_class_name()))
567 }
568}
569
570pub trait TextAlignUtilities {
572 fn text_align(self, align: TextAlign) -> Self;
574}
575
576impl TextAlignUtilities for ClassBuilder {
577 fn text_align(self, align: TextAlign) -> Self {
578 self.class(format!("text-{}", align.to_class_name()))
579 }
580}
581
582pub trait LineHeightUtilities {
584 fn line_height(self, height: LineHeight) -> Self;
586}
587
588impl LineHeightUtilities for ClassBuilder {
589 fn line_height(self, height: LineHeight) -> Self {
590 self.class(format!("leading-{}", height.to_class_name()))
591 }
592}
593
594pub trait LetterSpacingUtilities {
596 fn letter_spacing(self, spacing: LetterSpacing) -> Self;
598}
599
600impl LetterSpacingUtilities for ClassBuilder {
601 fn letter_spacing(self, spacing: LetterSpacing) -> Self {
602 self.class(format!("tracking-{}", spacing.to_class_name()))
603 }
604}
605
606pub trait TextDecorationUtilities {
608 fn text_decoration(self, decoration: TextDecoration) -> Self;
610}
611
612impl TextDecorationUtilities for ClassBuilder {
613 fn text_decoration(self, decoration: TextDecoration) -> Self {
614 self.class(decoration.to_class_name())
615 }
616}
617
618pub trait TextTransformUtilities {
620 fn text_transform(self, transform: TextTransform) -> Self;
622}
623
624impl TextTransformUtilities for ClassBuilder {
625 fn text_transform(self, transform: TextTransform) -> Self {
626 self.class(transform.to_class_name())
627 }
628}
629
630pub trait TextOverflowUtilities {
632 fn text_overflow(self, overflow: TextOverflow) -> Self;
634}
635
636impl TextOverflowUtilities for ClassBuilder {
637 fn text_overflow(self, overflow: TextOverflow) -> Self {
638 self.class(overflow.to_class_name())
639 }
640}
641
642pub trait WhiteSpaceUtilities {
644 fn white_space(self, space: WhiteSpace) -> Self;
646}
647
648impl WhiteSpaceUtilities for ClassBuilder {
649 fn white_space(self, space: WhiteSpace) -> Self {
650 self.class(space.to_class_name())
651 }
652}
653
654pub trait WordBreakUtilities {
656 fn word_break(self, break_type: WordBreak) -> Self;
658}
659
660impl WordBreakUtilities for ClassBuilder {
661 fn word_break(self, break_type: WordBreak) -> Self {
662 self.class(break_type.to_class_name())
663 }
664}
665
666#[cfg(test)]
667mod tests {
668 use super::*;
669
670 #[test]
671 fn test_font_family_utilities() {
672 let classes = ClassBuilder::new()
673 .font_family(FontFamily::Sans)
674 .font_family(FontFamily::Serif)
675 .font_family(FontFamily::Mono)
676 .build();
677
678 let css_classes = classes.to_css_classes();
679 assert!(css_classes.contains("font-sans"));
680 assert!(css_classes.contains("font-serif"));
681 assert!(css_classes.contains("font-mono"));
682 }
683
684 #[test]
685 fn test_font_size_utilities() {
686 let classes = ClassBuilder::new()
687 .font_size(FontSize::Xs)
688 .font_size(FontSize::Sm)
689 .font_size(FontSize::Base)
690 .font_size(FontSize::Lg)
691 .font_size(FontSize::Xl)
692 .build();
693
694 let css_classes = classes.to_css_classes();
695 assert!(css_classes.contains("text-xs"));
696 assert!(css_classes.contains("text-sm"));
697 assert!(css_classes.contains("text-base"));
698 assert!(css_classes.contains("text-lg"));
699 assert!(css_classes.contains("text-xl"));
700 }
701
702 #[test]
703 fn test_font_weight_utilities() {
704 let classes = ClassBuilder::new()
705 .font_weight(FontWeight::Thin)
706 .font_weight(FontWeight::Normal)
707 .font_weight(FontWeight::Bold)
708 .font_weight(FontWeight::Black)
709 .build();
710
711 let css_classes = classes.to_css_classes();
712 assert!(css_classes.contains("font-thin"));
713 assert!(css_classes.contains("font-normal"));
714 assert!(css_classes.contains("font-bold"));
715 assert!(css_classes.contains("font-black"));
716 }
717
718 #[test]
719 fn test_text_align_utilities() {
720 let classes = ClassBuilder::new()
721 .text_align(TextAlign::Left)
722 .text_align(TextAlign::Center)
723 .text_align(TextAlign::Right)
724 .text_align(TextAlign::Justify)
725 .build();
726
727 let css_classes = classes.to_css_classes();
728 assert!(css_classes.contains("text-left"));
729 assert!(css_classes.contains("text-center"));
730 assert!(css_classes.contains("text-right"));
731 assert!(css_classes.contains("text-justify"));
732 }
733
734 #[test]
735 fn test_line_height_utilities() {
736 let classes = ClassBuilder::new()
737 .line_height(LineHeight::Tight)
738 .line_height(LineHeight::Normal)
739 .line_height(LineHeight::Relaxed)
740 .line_height(LineHeight::Custom(1.75))
741 .build();
742
743 let css_classes = classes.to_css_classes();
744 assert!(css_classes.contains("leading-tight"));
745 assert!(css_classes.contains("leading-normal"));
746 assert!(css_classes.contains("leading-relaxed"));
747 assert!(css_classes.contains("leading-1.75"));
748 }
749
750 #[test]
751 fn test_letter_spacing_utilities() {
752 let classes = ClassBuilder::new()
753 .letter_spacing(LetterSpacing::Tight)
754 .letter_spacing(LetterSpacing::Normal)
755 .letter_spacing(LetterSpacing::Wide)
756 .letter_spacing(LetterSpacing::Custom(0.1))
757 .build();
758
759 let css_classes = classes.to_css_classes();
760 assert!(css_classes.contains("tracking-tight"));
761 assert!(css_classes.contains("tracking-normal"));
762 assert!(css_classes.contains("tracking-wide"));
763 assert!(css_classes.contains("tracking-0.1"));
764 }
765
766 #[test]
767 fn test_text_decoration_utilities() {
768 let classes = ClassBuilder::new()
769 .text_decoration(TextDecoration::None)
770 .text_decoration(TextDecoration::Underline)
771 .text_decoration(TextDecoration::LineThrough)
772 .build();
773
774 let css_classes = classes.to_css_classes();
775 assert!(css_classes.contains("no-underline"));
776 assert!(css_classes.contains("underline"));
777 assert!(css_classes.contains("line-through"));
778 }
779
780 #[test]
781 fn test_text_transform_utilities() {
782 let classes = ClassBuilder::new()
783 .text_transform(TextTransform::None)
784 .text_transform(TextTransform::Uppercase)
785 .text_transform(TextTransform::Lowercase)
786 .text_transform(TextTransform::Capitalize)
787 .build();
788
789 let css_classes = classes.to_css_classes();
790 assert!(css_classes.contains("normal-case"));
791 assert!(css_classes.contains("uppercase"));
792 assert!(css_classes.contains("lowercase"));
793 assert!(css_classes.contains("capitalize"));
794 }
795
796 #[test]
797 fn test_text_overflow_utilities() {
798 let classes = ClassBuilder::new()
799 .text_overflow(TextOverflow::Truncate)
800 .text_overflow(TextOverflow::Ellipsis)
801 .text_overflow(TextOverflow::Clip)
802 .build();
803
804 let css_classes = classes.to_css_classes();
805 assert!(css_classes.contains("truncate"));
806 assert!(css_classes.contains("text-ellipsis"));
807 assert!(css_classes.contains("text-clip"));
808 }
809
810 #[test]
811 fn test_white_space_utilities() {
812 let classes = ClassBuilder::new()
813 .white_space(WhiteSpace::Normal)
814 .white_space(WhiteSpace::Nowrap)
815 .white_space(WhiteSpace::Pre)
816 .build();
817
818 let css_classes = classes.to_css_classes();
819 assert!(css_classes.contains("whitespace-normal"));
820 assert!(css_classes.contains("whitespace-nowrap"));
821 assert!(css_classes.contains("whitespace-pre"));
822 }
823
824 #[test]
825 fn test_word_break_utilities() {
826 let classes = ClassBuilder::new()
827 .word_break(WordBreak::Normal)
828 .word_break(WordBreak::BreakAll)
829 .word_break(WordBreak::BreakWords)
830 .build();
831
832 let css_classes = classes.to_css_classes();
833 assert!(css_classes.contains("break-normal"));
834 assert!(css_classes.contains("break-all"));
835 assert!(css_classes.contains("break-words"));
836 }
837
838 #[test]
839 fn test_complex_typography_combination() {
840 let classes = ClassBuilder::new()
841 .font_family(FontFamily::Sans)
842 .font_size(FontSize::Lg)
843 .font_weight(FontWeight::Bold)
844 .text_align(TextAlign::Center)
845 .line_height(LineHeight::Relaxed)
846 .letter_spacing(LetterSpacing::Wide)
847 .text_decoration(TextDecoration::Underline)
848 .text_transform(TextTransform::Uppercase)
849 .build();
850
851 let css_classes = classes.to_css_classes();
852 assert!(css_classes.contains("font-sans"));
853 assert!(css_classes.contains("text-lg"));
854 assert!(css_classes.contains("font-bold"));
855 assert!(css_classes.contains("text-center"));
856 assert!(css_classes.contains("leading-relaxed"));
857 assert!(css_classes.contains("tracking-wide"));
858 assert!(css_classes.contains("underline"));
859 assert!(css_classes.contains("uppercase"));
860 }
861}