tailwind_rs_core/utilities/
borders.rs

1//! Border utilities for tailwind-rs
2//!
3//! This module provides utilities for border width, border style, border radius,
4//! border color, outline, and divide utilities.
5
6use crate::classes::ClassBuilder;
7use serde::{Deserialize, Serialize};
8use std::fmt;
9
10/// Border width values
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
12pub enum BorderWidth {
13    /// No border
14    Zero,
15    /// Thin border
16    Thin,
17    /// Default border
18    Default,
19    /// Medium border
20    Medium,
21    /// Thick border
22    Thick,
23}
24
25/// Border style values
26#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
27pub enum BorderStyle {
28    /// Solid border
29    Solid,
30    /// Dashed border
31    Dashed,
32    /// Dotted border
33    Dotted,
34    /// Double border
35    Double,
36    /// Hidden border
37    Hidden,
38    /// None border
39    None,
40}
41
42/// Border radius values
43#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
44pub enum BorderRadius {
45    /// No radius
46    None,
47    /// Small radius
48    Sm,
49    /// Default radius
50    Default,
51    /// Medium radius
52    Md,
53    /// Large radius
54    Lg,
55    /// Extra large radius
56    Xl,
57    /// 2x large radius
58    Xl2,
59    /// 3x large radius
60    Xl3,
61    /// Full radius
62    Full,
63}
64
65/// Outline width values
66#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
67pub enum OutlineWidth {
68    /// No outline
69    Zero,
70    /// Thin outline
71    Thin,
72    /// Default outline
73    Default,
74    /// Medium outline
75    Medium,
76    /// Thick outline
77    Thick,
78}
79
80/// Outline style values
81#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
82pub enum OutlineStyle {
83    /// Solid outline
84    Solid,
85    /// Dashed outline
86    Dashed,
87    /// Dotted outline
88    Dotted,
89    /// Double outline
90    Double,
91    /// Hidden outline
92    Hidden,
93    /// None outline
94    None,
95}
96
97/// Outline offset values
98#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
99pub enum OutlineOffset {
100    /// No offset
101    Zero,
102    /// Small offset
103    One,
104    /// Medium offset
105    Two,
106    /// Large offset
107    Four,
108    /// Extra large offset
109    Eight,
110}
111
112/// Divide width values
113#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
114pub enum DivideWidth {
115    /// No divide
116    Zero,
117    /// Thin divide
118    Thin,
119    /// Default divide
120    Default,
121    /// Medium divide
122    Medium,
123    /// Thick divide
124    Thick,
125}
126
127/// Divide style values
128#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
129pub enum DivideStyle {
130    /// Solid divide
131    Solid,
132    /// Dashed divide
133    Dashed,
134    /// Dotted divide
135    Dotted,
136    /// Double divide
137    Double,
138    /// Hidden divide
139    Hidden,
140    /// None divide
141    None,
142}
143
144/// Ring width values
145#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
146pub enum RingWidth {
147    /// No ring
148    Zero,
149    /// Thin ring
150    Thin,
151    /// Default ring
152    Default,
153    /// Medium ring
154    Medium,
155    /// Thick ring
156    Thick,
157    /// Extra thick ring
158    ExtraThick,
159}
160
161/// Ring offset width values
162#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
163pub enum RingOffsetWidth {
164    /// No offset
165    Zero,
166    /// Small offset
167    One,
168    /// Medium offset
169    Two,
170    /// Large offset
171    Four,
172    /// Extra large offset
173    Eight,
174}
175
176impl BorderWidth {
177    pub fn to_class_name(&self) -> String {
178        match self {
179            BorderWidth::Zero => "0".to_string(),
180            BorderWidth::Thin => "thin".to_string(),
181            BorderWidth::Default => "default".to_string(),
182            BorderWidth::Medium => "medium".to_string(),
183            BorderWidth::Thick => "thick".to_string(),
184        }
185    }
186    
187    pub fn to_css_value(&self) -> String {
188        match self {
189            BorderWidth::Zero => "0px".to_string(),
190            BorderWidth::Thin => "1px".to_string(),
191            BorderWidth::Default => "1px".to_string(),
192            BorderWidth::Medium => "2px".to_string(),
193            BorderWidth::Thick => "4px".to_string(),
194        }
195    }
196}
197
198impl BorderStyle {
199    pub fn to_class_name(&self) -> String {
200        match self {
201            BorderStyle::Solid => "solid".to_string(),
202            BorderStyle::Dashed => "dashed".to_string(),
203            BorderStyle::Dotted => "dotted".to_string(),
204            BorderStyle::Double => "double".to_string(),
205            BorderStyle::Hidden => "hidden".to_string(),
206            BorderStyle::None => "none".to_string(),
207        }
208    }
209    
210    pub fn to_css_value(&self) -> String {
211        match self {
212            BorderStyle::Solid => "solid".to_string(),
213            BorderStyle::Dashed => "dashed".to_string(),
214            BorderStyle::Dotted => "dotted".to_string(),
215            BorderStyle::Double => "double".to_string(),
216            BorderStyle::Hidden => "hidden".to_string(),
217            BorderStyle::None => "none".to_string(),
218        }
219    }
220}
221
222impl BorderRadius {
223    pub fn to_class_name(&self) -> String {
224        match self {
225            BorderRadius::None => "none".to_string(),
226            BorderRadius::Sm => "sm".to_string(),
227            BorderRadius::Default => "default".to_string(),
228            BorderRadius::Md => "md".to_string(),
229            BorderRadius::Lg => "lg".to_string(),
230            BorderRadius::Xl => "xl".to_string(),
231            BorderRadius::Xl2 => "2xl".to_string(),
232            BorderRadius::Xl3 => "3xl".to_string(),
233            BorderRadius::Full => "full".to_string(),
234        }
235    }
236    
237    pub fn to_css_value(&self) -> String {
238        match self {
239            BorderRadius::None => "0px".to_string(),
240            BorderRadius::Sm => "0.125rem".to_string(),
241            BorderRadius::Default => "0.25rem".to_string(),
242            BorderRadius::Md => "0.375rem".to_string(),
243            BorderRadius::Lg => "0.5rem".to_string(),
244            BorderRadius::Xl => "0.75rem".to_string(),
245            BorderRadius::Xl2 => "1rem".to_string(),
246            BorderRadius::Xl3 => "1.5rem".to_string(),
247            BorderRadius::Full => "9999px".to_string(),
248        }
249    }
250}
251
252impl OutlineWidth {
253    pub fn to_class_name(&self) -> String {
254        match self {
255            OutlineWidth::Zero => "0".to_string(),
256            OutlineWidth::Thin => "thin".to_string(),
257            OutlineWidth::Default => "default".to_string(),
258            OutlineWidth::Medium => "medium".to_string(),
259            OutlineWidth::Thick => "thick".to_string(),
260        }
261    }
262    
263    pub fn to_css_value(&self) -> String {
264        match self {
265            OutlineWidth::Zero => "0px".to_string(),
266            OutlineWidth::Thin => "1px".to_string(),
267            OutlineWidth::Default => "2px".to_string(),
268            OutlineWidth::Medium => "4px".to_string(),
269            OutlineWidth::Thick => "8px".to_string(),
270        }
271    }
272}
273
274impl OutlineStyle {
275    pub fn to_class_name(&self) -> String {
276        match self {
277            OutlineStyle::Solid => "solid".to_string(),
278            OutlineStyle::Dashed => "dashed".to_string(),
279            OutlineStyle::Dotted => "dotted".to_string(),
280            OutlineStyle::Double => "double".to_string(),
281            OutlineStyle::Hidden => "hidden".to_string(),
282            OutlineStyle::None => "none".to_string(),
283        }
284    }
285    
286    pub fn to_css_value(&self) -> String {
287        match self {
288            OutlineStyle::Solid => "solid".to_string(),
289            OutlineStyle::Dashed => "dashed".to_string(),
290            OutlineStyle::Dotted => "dotted".to_string(),
291            OutlineStyle::Double => "double".to_string(),
292            OutlineStyle::Hidden => "hidden".to_string(),
293            OutlineStyle::None => "none".to_string(),
294        }
295    }
296}
297
298impl OutlineOffset {
299    pub fn to_class_name(&self) -> String {
300        match self {
301            OutlineOffset::Zero => "0".to_string(),
302            OutlineOffset::One => "1".to_string(),
303            OutlineOffset::Two => "2".to_string(),
304            OutlineOffset::Four => "4".to_string(),
305            OutlineOffset::Eight => "8".to_string(),
306        }
307    }
308    
309    pub fn to_css_value(&self) -> String {
310        match self {
311            OutlineOffset::Zero => "0px".to_string(),
312            OutlineOffset::One => "1px".to_string(),
313            OutlineOffset::Two => "2px".to_string(),
314            OutlineOffset::Four => "4px".to_string(),
315            OutlineOffset::Eight => "8px".to_string(),
316        }
317    }
318}
319
320impl DivideWidth {
321    pub fn to_class_name(&self) -> String {
322        match self {
323            DivideWidth::Zero => "0".to_string(),
324            DivideWidth::Thin => "thin".to_string(),
325            DivideWidth::Default => "default".to_string(),
326            DivideWidth::Medium => "medium".to_string(),
327            DivideWidth::Thick => "thick".to_string(),
328        }
329    }
330    
331    pub fn to_css_value(&self) -> String {
332        match self {
333            DivideWidth::Zero => "0px".to_string(),
334            DivideWidth::Thin => "1px".to_string(),
335            DivideWidth::Default => "1px".to_string(),
336            DivideWidth::Medium => "2px".to_string(),
337            DivideWidth::Thick => "4px".to_string(),
338        }
339    }
340}
341
342impl DivideStyle {
343    pub fn to_class_name(&self) -> String {
344        match self {
345            DivideStyle::Solid => "solid".to_string(),
346            DivideStyle::Dashed => "dashed".to_string(),
347            DivideStyle::Dotted => "dotted".to_string(),
348            DivideStyle::Double => "double".to_string(),
349            DivideStyle::Hidden => "hidden".to_string(),
350            DivideStyle::None => "none".to_string(),
351        }
352    }
353    
354    pub fn to_css_value(&self) -> String {
355        match self {
356            DivideStyle::Solid => "solid".to_string(),
357            DivideStyle::Dashed => "dashed".to_string(),
358            DivideStyle::Dotted => "dotted".to_string(),
359            DivideStyle::Double => "double".to_string(),
360            DivideStyle::Hidden => "hidden".to_string(),
361            DivideStyle::None => "none".to_string(),
362        }
363    }
364}
365
366impl RingWidth {
367    pub fn to_class_name(&self) -> String {
368        match self {
369            RingWidth::Zero => "0".to_string(),
370            RingWidth::Thin => "thin".to_string(),
371            RingWidth::Default => "default".to_string(),
372            RingWidth::Medium => "medium".to_string(),
373            RingWidth::Thick => "thick".to_string(),
374            RingWidth::ExtraThick => "extra-thick".to_string(),
375        }
376    }
377    
378    pub fn to_css_value(&self) -> String {
379        match self {
380            RingWidth::Zero => "0px".to_string(),
381            RingWidth::Thin => "1px".to_string(),
382            RingWidth::Default => "3px".to_string(),
383            RingWidth::Medium => "4px".to_string(),
384            RingWidth::Thick => "8px".to_string(),
385            RingWidth::ExtraThick => "12px".to_string(),
386        }
387    }
388}
389
390impl RingOffsetWidth {
391    pub fn to_class_name(&self) -> String {
392        match self {
393            RingOffsetWidth::Zero => "0".to_string(),
394            RingOffsetWidth::One => "1".to_string(),
395            RingOffsetWidth::Two => "2".to_string(),
396            RingOffsetWidth::Four => "4".to_string(),
397            RingOffsetWidth::Eight => "8".to_string(),
398        }
399    }
400    
401    pub fn to_css_value(&self) -> String {
402        match self {
403            RingOffsetWidth::Zero => "0px".to_string(),
404            RingOffsetWidth::One => "1px".to_string(),
405            RingOffsetWidth::Two => "2px".to_string(),
406            RingOffsetWidth::Four => "4px".to_string(),
407            RingOffsetWidth::Eight => "8px".to_string(),
408        }
409    }
410}
411
412impl fmt::Display for BorderWidth {
413    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
414        write!(f, "{}", self.to_class_name())
415    }
416}
417
418impl fmt::Display for BorderStyle {
419    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
420        write!(f, "{}", self.to_class_name())
421    }
422}
423
424impl fmt::Display for BorderRadius {
425    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
426        write!(f, "{}", self.to_class_name())
427    }
428}
429
430impl fmt::Display for OutlineWidth {
431    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
432        write!(f, "{}", self.to_class_name())
433    }
434}
435
436impl fmt::Display for OutlineStyle {
437    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
438        write!(f, "{}", self.to_class_name())
439    }
440}
441
442impl fmt::Display for OutlineOffset {
443    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
444        write!(f, "{}", self.to_class_name())
445    }
446}
447
448impl fmt::Display for DivideWidth {
449    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
450        write!(f, "{}", self.to_class_name())
451    }
452}
453
454impl fmt::Display for DivideStyle {
455    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
456        write!(f, "{}", self.to_class_name())
457    }
458}
459
460impl fmt::Display for RingWidth {
461    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
462        write!(f, "{}", self.to_class_name())
463    }
464}
465
466impl fmt::Display for RingOffsetWidth {
467    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
468        write!(f, "{}", self.to_class_name())
469    }
470}
471
472/// Trait for adding border width utilities to a class builder
473pub trait BorderWidthUtilities {
474    fn border_width(self, width: BorderWidth) -> Self;
475    fn border_width_x(self, width: BorderWidth) -> Self;
476    fn border_width_y(self, width: BorderWidth) -> Self;
477    fn border_width_t(self, width: BorderWidth) -> Self;
478    fn border_width_r(self, width: BorderWidth) -> Self;
479    fn border_width_b(self, width: BorderWidth) -> Self;
480    fn border_width_l(self, width: BorderWidth) -> Self;
481}
482
483impl BorderWidthUtilities for ClassBuilder {
484    fn border_width(self, width: BorderWidth) -> Self {
485        self.class(format!("border-{}", width.to_class_name()))
486    }
487    
488    fn border_width_x(self, width: BorderWidth) -> Self {
489        self.class(format!("border-x-{}", width.to_class_name()))
490    }
491    
492    fn border_width_y(self, width: BorderWidth) -> Self {
493        self.class(format!("border-y-{}", width.to_class_name()))
494    }
495    
496    fn border_width_t(self, width: BorderWidth) -> Self {
497        self.class(format!("border-t-{}", width.to_class_name()))
498    }
499    
500    fn border_width_r(self, width: BorderWidth) -> Self {
501        self.class(format!("border-r-{}", width.to_class_name()))
502    }
503    
504    fn border_width_b(self, width: BorderWidth) -> Self {
505        self.class(format!("border-b-{}", width.to_class_name()))
506    }
507    
508    fn border_width_l(self, width: BorderWidth) -> Self {
509        self.class(format!("border-l-{}", width.to_class_name()))
510    }
511}
512
513/// Trait for adding border style utilities to a class builder
514pub trait BorderStyleUtilities {
515    fn border_style(self, style: BorderStyle) -> Self;
516}
517
518impl BorderStyleUtilities for ClassBuilder {
519    fn border_style(self, style: BorderStyle) -> Self {
520        self.class(format!("border-{}", style.to_class_name()))
521    }
522}
523
524/// Trait for adding border radius utilities to a class builder
525pub trait BorderRadiusUtilities {
526    fn border_radius(self, radius: BorderRadius) -> Self;
527    fn border_radius_t(self, radius: BorderRadius) -> Self;
528    fn border_radius_r(self, radius: BorderRadius) -> Self;
529    fn border_radius_b(self, radius: BorderRadius) -> Self;
530    fn border_radius_l(self, radius: BorderRadius) -> Self;
531    fn border_radius_tl(self, radius: BorderRadius) -> Self;
532    fn border_radius_tr(self, radius: BorderRadius) -> Self;
533    fn border_radius_br(self, radius: BorderRadius) -> Self;
534    fn border_radius_bl(self, radius: BorderRadius) -> Self;
535}
536
537impl BorderRadiusUtilities for ClassBuilder {
538    fn border_radius(self, radius: BorderRadius) -> Self {
539        self.class(format!("rounded-{}", radius.to_class_name()))
540    }
541    
542    fn border_radius_t(self, radius: BorderRadius) -> Self {
543        self.class(format!("rounded-t-{}", radius.to_class_name()))
544    }
545    
546    fn border_radius_r(self, radius: BorderRadius) -> Self {
547        self.class(format!("rounded-r-{}", radius.to_class_name()))
548    }
549    
550    fn border_radius_b(self, radius: BorderRadius) -> Self {
551        self.class(format!("rounded-b-{}", radius.to_class_name()))
552    }
553    
554    fn border_radius_l(self, radius: BorderRadius) -> Self {
555        self.class(format!("rounded-l-{}", radius.to_class_name()))
556    }
557    
558    fn border_radius_tl(self, radius: BorderRadius) -> Self {
559        self.class(format!("rounded-tl-{}", radius.to_class_name()))
560    }
561    
562    fn border_radius_tr(self, radius: BorderRadius) -> Self {
563        self.class(format!("rounded-tr-{}", radius.to_class_name()))
564    }
565    
566    fn border_radius_br(self, radius: BorderRadius) -> Self {
567        self.class(format!("rounded-br-{}", radius.to_class_name()))
568    }
569    
570    fn border_radius_bl(self, radius: BorderRadius) -> Self {
571        self.class(format!("rounded-bl-{}", radius.to_class_name()))
572    }
573}
574
575/// Trait for adding outline utilities to a class builder
576pub trait OutlineUtilities {
577    fn outline_width(self, width: OutlineWidth) -> Self;
578    fn outline_style(self, style: OutlineStyle) -> Self;
579    fn outline_offset(self, offset: OutlineOffset) -> Self;
580}
581
582impl OutlineUtilities for ClassBuilder {
583    fn outline_width(self, width: OutlineWidth) -> Self {
584        self.class(format!("outline-{}", width.to_class_name()))
585    }
586    
587    fn outline_style(self, style: OutlineStyle) -> Self {
588        self.class(format!("outline-{}", style.to_class_name()))
589    }
590    
591    fn outline_offset(self, offset: OutlineOffset) -> Self {
592        self.class(format!("outline-offset-{}", offset.to_class_name()))
593    }
594}
595
596/// Trait for adding divide utilities to a class builder
597pub trait DivideUtilities {
598    fn divide_width(self, width: DivideWidth) -> Self;
599    fn divide_width_x(self, width: DivideWidth) -> Self;
600    fn divide_width_y(self, width: DivideWidth) -> Self;
601    fn divide_style(self, style: DivideStyle) -> Self;
602}
603
604impl DivideUtilities for ClassBuilder {
605    fn divide_width(self, width: DivideWidth) -> Self {
606        self.class(format!("divide-{}", width.to_class_name()))
607    }
608    
609    fn divide_width_x(self, width: DivideWidth) -> Self {
610        self.class(format!("divide-x-{}", width.to_class_name()))
611    }
612    
613    fn divide_width_y(self, width: DivideWidth) -> Self {
614        self.class(format!("divide-y-{}", width.to_class_name()))
615    }
616    
617    fn divide_style(self, style: DivideStyle) -> Self {
618        self.class(format!("divide-{}", style.to_class_name()))
619    }
620}
621
622/// Trait for adding ring utilities to a class builder
623pub trait RingUtilities {
624    fn ring_width(self, width: RingWidth) -> Self;
625    fn ring_offset_width(self, width: RingOffsetWidth) -> Self;
626}
627
628impl RingUtilities for ClassBuilder {
629    fn ring_width(self, width: RingWidth) -> Self {
630        self.class(format!("ring-{}", width.to_class_name()))
631    }
632    
633    fn ring_offset_width(self, width: RingOffsetWidth) -> Self {
634        self.class(format!("ring-offset-{}", width.to_class_name()))
635    }
636}
637
638#[cfg(test)]
639mod tests {
640    use super::*;
641    
642    #[test]
643    fn test_border_width_utilities() {
644        let classes = ClassBuilder::new()
645            .border_width(BorderWidth::Zero)
646            .border_width(BorderWidth::Thin)
647            .border_width(BorderWidth::Default)
648            .border_width(BorderWidth::Medium)
649            .border_width(BorderWidth::Thick)
650            .border_width_x(BorderWidth::Thin)
651            .border_width_y(BorderWidth::Medium)
652            .border_width_t(BorderWidth::Thick)
653            .border_width_r(BorderWidth::Default)
654            .border_width_b(BorderWidth::Thin)
655            .border_width_l(BorderWidth::Zero)
656            .build();
657        
658        let css_classes = classes.to_css_classes();
659        assert!(css_classes.contains("border-0"));
660        assert!(css_classes.contains("border-thin"));
661        assert!(css_classes.contains("border-default"));
662        assert!(css_classes.contains("border-medium"));
663        assert!(css_classes.contains("border-thick"));
664        assert!(css_classes.contains("border-x-thin"));
665        assert!(css_classes.contains("border-y-medium"));
666        assert!(css_classes.contains("border-t-thick"));
667        assert!(css_classes.contains("border-r-default"));
668        assert!(css_classes.contains("border-b-thin"));
669        assert!(css_classes.contains("border-l-0"));
670    }
671    
672    #[test]
673    fn test_border_style_utilities() {
674        let classes = ClassBuilder::new()
675            .border_style(BorderStyle::Solid)
676            .border_style(BorderStyle::Dashed)
677            .border_style(BorderStyle::Dotted)
678            .border_style(BorderStyle::Double)
679            .border_style(BorderStyle::Hidden)
680            .border_style(BorderStyle::None)
681            .build();
682        
683        let css_classes = classes.to_css_classes();
684        assert!(css_classes.contains("border-solid"));
685        assert!(css_classes.contains("border-dashed"));
686        assert!(css_classes.contains("border-dotted"));
687        assert!(css_classes.contains("border-double"));
688        assert!(css_classes.contains("border-hidden"));
689        assert!(css_classes.contains("border-none"));
690    }
691    
692    #[test]
693    fn test_border_radius_utilities() {
694        let classes = ClassBuilder::new()
695            .border_radius(BorderRadius::None)
696            .border_radius(BorderRadius::Sm)
697            .border_radius(BorderRadius::Default)
698            .border_radius(BorderRadius::Md)
699            .border_radius(BorderRadius::Lg)
700            .border_radius(BorderRadius::Xl)
701            .border_radius(BorderRadius::Xl2)
702            .border_radius(BorderRadius::Xl3)
703            .border_radius(BorderRadius::Full)
704            .border_radius_t(BorderRadius::Lg)
705            .border_radius_r(BorderRadius::Md)
706            .border_radius_b(BorderRadius::Sm)
707            .border_radius_l(BorderRadius::Default)
708            .border_radius_tl(BorderRadius::Xl)
709            .border_radius_tr(BorderRadius::Xl2)
710            .border_radius_br(BorderRadius::Xl3)
711            .border_radius_bl(BorderRadius::Full)
712            .build();
713        
714        let css_classes = classes.to_css_classes();
715        assert!(css_classes.contains("rounded-none"));
716        assert!(css_classes.contains("rounded-sm"));
717        assert!(css_classes.contains("rounded-default"));
718        assert!(css_classes.contains("rounded-md"));
719        assert!(css_classes.contains("rounded-lg"));
720        assert!(css_classes.contains("rounded-xl"));
721        assert!(css_classes.contains("rounded-2xl"));
722        assert!(css_classes.contains("rounded-3xl"));
723        assert!(css_classes.contains("rounded-full"));
724        assert!(css_classes.contains("rounded-t-lg"));
725        assert!(css_classes.contains("rounded-r-md"));
726        assert!(css_classes.contains("rounded-b-sm"));
727        assert!(css_classes.contains("rounded-l-default"));
728        assert!(css_classes.contains("rounded-tl-xl"));
729        assert!(css_classes.contains("rounded-tr-2xl"));
730        assert!(css_classes.contains("rounded-br-3xl"));
731        assert!(css_classes.contains("rounded-bl-full"));
732    }
733    
734    #[test]
735    fn test_outline_utilities() {
736        let classes = ClassBuilder::new()
737            .outline_width(OutlineWidth::Zero)
738            .outline_width(OutlineWidth::Thin)
739            .outline_width(OutlineWidth::Default)
740            .outline_width(OutlineWidth::Medium)
741            .outline_width(OutlineWidth::Thick)
742            .outline_style(OutlineStyle::Solid)
743            .outline_style(OutlineStyle::Dashed)
744            .outline_style(OutlineStyle::Dotted)
745            .outline_style(OutlineStyle::Double)
746            .outline_style(OutlineStyle::Hidden)
747            .outline_style(OutlineStyle::None)
748            .outline_offset(OutlineOffset::Zero)
749            .outline_offset(OutlineOffset::One)
750            .outline_offset(OutlineOffset::Two)
751            .outline_offset(OutlineOffset::Four)
752            .outline_offset(OutlineOffset::Eight)
753            .build();
754        
755        let css_classes = classes.to_css_classes();
756        assert!(css_classes.contains("outline-0"));
757        assert!(css_classes.contains("outline-thin"));
758        assert!(css_classes.contains("outline-default"));
759        assert!(css_classes.contains("outline-medium"));
760        assert!(css_classes.contains("outline-thick"));
761        assert!(css_classes.contains("outline-solid"));
762        assert!(css_classes.contains("outline-dashed"));
763        assert!(css_classes.contains("outline-dotted"));
764        assert!(css_classes.contains("outline-double"));
765        assert!(css_classes.contains("outline-hidden"));
766        assert!(css_classes.contains("outline-none"));
767        assert!(css_classes.contains("outline-offset-0"));
768        assert!(css_classes.contains("outline-offset-1"));
769        assert!(css_classes.contains("outline-offset-2"));
770        assert!(css_classes.contains("outline-offset-4"));
771        assert!(css_classes.contains("outline-offset-8"));
772    }
773    
774    #[test]
775    fn test_divide_utilities() {
776        let classes = ClassBuilder::new()
777            .divide_width(DivideWidth::Zero)
778            .divide_width(DivideWidth::Thin)
779            .divide_width(DivideWidth::Default)
780            .divide_width(DivideWidth::Medium)
781            .divide_width(DivideWidth::Thick)
782            .divide_width_x(DivideWidth::Thin)
783            .divide_width_y(DivideWidth::Medium)
784            .divide_style(DivideStyle::Solid)
785            .divide_style(DivideStyle::Dashed)
786            .divide_style(DivideStyle::Dotted)
787            .divide_style(DivideStyle::Double)
788            .divide_style(DivideStyle::Hidden)
789            .divide_style(DivideStyle::None)
790            .build();
791        
792        let css_classes = classes.to_css_classes();
793        assert!(css_classes.contains("divide-0"));
794        assert!(css_classes.contains("divide-thin"));
795        assert!(css_classes.contains("divide-default"));
796        assert!(css_classes.contains("divide-medium"));
797        assert!(css_classes.contains("divide-thick"));
798        assert!(css_classes.contains("divide-x-thin"));
799        assert!(css_classes.contains("divide-y-medium"));
800        assert!(css_classes.contains("divide-solid"));
801        assert!(css_classes.contains("divide-dashed"));
802        assert!(css_classes.contains("divide-dotted"));
803        assert!(css_classes.contains("divide-double"));
804        assert!(css_classes.contains("divide-hidden"));
805        assert!(css_classes.contains("divide-none"));
806    }
807    
808    #[test]
809    fn test_ring_utilities() {
810        let classes = ClassBuilder::new()
811            .ring_width(RingWidth::Zero)
812            .ring_width(RingWidth::Thin)
813            .ring_width(RingWidth::Default)
814            .ring_width(RingWidth::Medium)
815            .ring_width(RingWidth::Thick)
816            .ring_width(RingWidth::ExtraThick)
817            .ring_offset_width(RingOffsetWidth::Zero)
818            .ring_offset_width(RingOffsetWidth::One)
819            .ring_offset_width(RingOffsetWidth::Two)
820            .ring_offset_width(RingOffsetWidth::Four)
821            .ring_offset_width(RingOffsetWidth::Eight)
822            .build();
823        
824        let css_classes = classes.to_css_classes();
825        assert!(css_classes.contains("ring-0"));
826        assert!(css_classes.contains("ring-thin"));
827        assert!(css_classes.contains("ring-default"));
828        assert!(css_classes.contains("ring-medium"));
829        assert!(css_classes.contains("ring-thick"));
830        assert!(css_classes.contains("ring-extra-thick"));
831        assert!(css_classes.contains("ring-offset-0"));
832        assert!(css_classes.contains("ring-offset-1"));
833        assert!(css_classes.contains("ring-offset-2"));
834        assert!(css_classes.contains("ring-offset-4"));
835        assert!(css_classes.contains("ring-offset-8"));
836    }
837    
838    #[test]
839    fn test_complex_border_combination() {
840        let classes = ClassBuilder::new()
841            .border_width(BorderWidth::Medium)
842            .border_style(BorderStyle::Solid)
843            .border_radius(BorderRadius::Lg)
844            .outline_width(OutlineWidth::Thin)
845            .outline_style(OutlineStyle::Dashed)
846            .outline_offset(OutlineOffset::Two)
847            .divide_width(DivideWidth::Thin)
848            .divide_style(DivideStyle::Solid)
849            .ring_width(RingWidth::Default)
850            .ring_offset_width(RingOffsetWidth::One)
851            .build();
852        
853        let css_classes = classes.to_css_classes();
854        assert!(css_classes.contains("border-medium"));
855        assert!(css_classes.contains("border-solid"));
856        assert!(css_classes.contains("rounded-lg"));
857        assert!(css_classes.contains("outline-thin"));
858        assert!(css_classes.contains("outline-dashed"));
859        assert!(css_classes.contains("outline-offset-2"));
860        assert!(css_classes.contains("divide-thin"));
861        assert!(css_classes.contains("divide-solid"));
862        assert!(css_classes.contains("ring-default"));
863        assert!(css_classes.contains("ring-offset-1"));
864    }
865    
866    /// Test that all Week 7 border utilities are implemented
867    #[test]
868    fn test_week7_border_utilities() {
869        // Test all Week 7 border utilities
870        let classes = ClassBuilder::new()
871            // Border Radius
872            .border_radius(BorderRadius::None)
873            .border_radius(BorderRadius::Sm)
874            .border_radius(BorderRadius::Default)
875            .border_radius(BorderRadius::Md)
876            .border_radius(BorderRadius::Lg)
877            .border_radius(BorderRadius::Xl)
878            .border_radius(BorderRadius::Xl2)
879            .border_radius(BorderRadius::Xl3)
880            .border_radius(BorderRadius::Full)
881            // Border Width & Style
882            .border_width(BorderWidth::Zero)
883            .border_width(BorderWidth::Thin)
884            .border_width(BorderWidth::Default)
885            .border_width(BorderWidth::Medium)
886            .border_width(BorderWidth::Thick)
887            .border_style(BorderStyle::Solid)
888            .border_style(BorderStyle::Dashed)
889            .border_style(BorderStyle::Dotted)
890            .border_style(BorderStyle::Double)
891            .border_style(BorderStyle::None)
892            .build();
893        
894        let css_classes = classes.to_css_classes();
895        
896        // Border Radius
897        assert!(css_classes.contains("rounded-none"));
898        assert!(css_classes.contains("rounded-sm"));
899        assert!(css_classes.contains("rounded"));
900        assert!(css_classes.contains("rounded-md"));
901        assert!(css_classes.contains("rounded-lg"));
902        assert!(css_classes.contains("rounded-xl"));
903        assert!(css_classes.contains("rounded-2xl"));
904        assert!(css_classes.contains("rounded-3xl"));
905        assert!(css_classes.contains("rounded-full"));
906        
907        // Border Width & Style
908        assert!(css_classes.contains("border-0"));
909        assert!(css_classes.contains("border-thin"));
910        assert!(css_classes.contains("border-default"));
911        assert!(css_classes.contains("border-medium"));
912        assert!(css_classes.contains("border-thick"));
913        assert!(css_classes.contains("border-solid"));
914        assert!(css_classes.contains("border-dashed"));
915        assert!(css_classes.contains("border-dotted"));
916        assert!(css_classes.contains("border-double"));
917        assert!(css_classes.contains("border-none"));
918    }
919}