tailwind_rs_core/utilities/
layout.rs

1//! Layout utilities for tailwind-rs
2//!
3//! This module provides utilities for display, position, overflow, z-index, and other layout properties.
4
5use crate::classes::ClassBuilder;
6use serde::{Deserialize, Serialize};
7use std::fmt;
8
9/// Display values
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
11pub enum Display {
12    /// Block display
13    Block,
14    /// Inline display
15    Inline,
16    /// Inline-block display
17    InlineBlock,
18    /// Flex display
19    Flex,
20    /// Inline-flex display
21    InlineFlex,
22    /// Grid display
23    Grid,
24    /// Inline-grid display
25    InlineGrid,
26    /// Table display
27    Table,
28    /// Inline-table display
29    InlineTable,
30    /// Table-caption display
31    TableCaption,
32    /// Table-cell display
33    TableCell,
34    /// Table-column display
35    TableColumn,
36    /// Table-column-group display
37    TableColumnGroup,
38    /// Table-footer-group display
39    TableFooterGroup,
40    /// Table-header-group display
41    TableHeaderGroup,
42    /// Table-row display
43    TableRow,
44    /// Table-row-group display
45    TableRowGroup,
46    /// Flow-root display
47    FlowRoot,
48    /// Contents display
49    Contents,
50    /// List-item display
51    ListItem,
52    /// Hidden display
53    Hidden,
54}
55
56/// Position values
57#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
58pub enum Position {
59    /// Static position
60    Static,
61    /// Fixed position
62    Fixed,
63    /// Absolute position
64    Absolute,
65    /// Relative position
66    Relative,
67    /// Sticky position
68    Sticky,
69}
70
71/// Overflow values
72#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
73pub enum Overflow {
74    /// Auto overflow
75    Auto,
76    /// Hidden overflow
77    Hidden,
78    /// Clip overflow
79    Clip,
80    /// Visible overflow
81    Visible,
82    /// Scroll overflow
83    Scroll,
84}
85
86/// Z-index values
87#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
88pub enum ZIndex {
89    /// Auto z-index
90    Auto,
91    /// Z-index 0
92    Zero,
93    /// Z-index 10
94    Ten,
95    /// Z-index 20
96    Twenty,
97    /// Z-index 30
98    Thirty,
99    /// Z-index 40
100    Forty,
101    /// Z-index 50
102    Fifty,
103}
104
105/// Float values
106#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
107pub enum Float {
108    /// Float right
109    Right,
110    /// Float left
111    Left,
112    /// Float none
113    None,
114}
115
116/// Clear values
117#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
118pub enum Clear {
119    /// Clear left
120    Left,
121    /// Clear right
122    Right,
123    /// Clear both
124    Both,
125    /// Clear none
126    None,
127}
128
129/// Isolation values
130#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
131pub enum Isolation {
132    /// Isolate
133    Isolate,
134    /// Isolate auto
135    Auto,
136}
137
138/// Object fit values
139#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
140pub enum ObjectFit {
141    /// Contain object fit
142    Contain,
143    /// Cover object fit
144    Cover,
145    /// Fill object fit
146    Fill,
147    /// None object fit
148    None,
149    /// Scale-down object fit
150    ScaleDown,
151}
152
153/// Object position values
154#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
155pub enum ObjectPosition {
156    /// Bottom object position
157    Bottom,
158    /// Center object position
159    Center,
160    /// Left object position
161    Left,
162    /// Left bottom object position
163    LeftBottom,
164    /// Left top object position
165    LeftTop,
166    /// Right object position
167    Right,
168    /// Right bottom object position
169    RightBottom,
170    /// Right top object position
171    RightTop,
172    /// Top object position
173    Top,
174}
175
176/// Overscroll behavior values
177#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
178pub enum OverscrollBehavior {
179    /// Auto overscroll behavior
180    Auto,
181    /// Contain overscroll behavior
182    Contain,
183    /// None overscroll behavior
184    None,
185}
186
187/// Visibility values
188#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
189pub enum Visibility {
190    /// Visible
191    Visible,
192    /// Hidden
193    Hidden,
194    /// Collapse
195    Collapse,
196}
197
198impl Display {
199    pub fn to_class_name(&self) -> String {
200        match self {
201            Display::Block => "block".to_string(),
202            Display::Inline => "inline".to_string(),
203            Display::InlineBlock => "inline-block".to_string(),
204            Display::Flex => "flex".to_string(),
205            Display::InlineFlex => "inline-flex".to_string(),
206            Display::Grid => "grid".to_string(),
207            Display::InlineGrid => "inline-grid".to_string(),
208            Display::Table => "table".to_string(),
209            Display::InlineTable => "inline-table".to_string(),
210            Display::TableCaption => "table-caption".to_string(),
211            Display::TableCell => "table-cell".to_string(),
212            Display::TableColumn => "table-column".to_string(),
213            Display::TableColumnGroup => "table-column-group".to_string(),
214            Display::TableFooterGroup => "table-footer-group".to_string(),
215            Display::TableHeaderGroup => "table-header-group".to_string(),
216            Display::TableRow => "table-row".to_string(),
217            Display::TableRowGroup => "table-row-group".to_string(),
218            Display::FlowRoot => "flow-root".to_string(),
219            Display::Contents => "contents".to_string(),
220            Display::ListItem => "list-item".to_string(),
221            Display::Hidden => "hidden".to_string(),
222        }
223    }
224    
225    pub fn to_css_value(&self) -> String {
226        match self {
227            Display::Block => "block".to_string(),
228            Display::Inline => "inline".to_string(),
229            Display::InlineBlock => "inline-block".to_string(),
230            Display::Flex => "flex".to_string(),
231            Display::InlineFlex => "inline-flex".to_string(),
232            Display::Grid => "grid".to_string(),
233            Display::InlineGrid => "inline-grid".to_string(),
234            Display::Table => "table".to_string(),
235            Display::InlineTable => "inline-table".to_string(),
236            Display::TableCaption => "table-caption".to_string(),
237            Display::TableCell => "table-cell".to_string(),
238            Display::TableColumn => "table-column".to_string(),
239            Display::TableColumnGroup => "table-column-group".to_string(),
240            Display::TableFooterGroup => "table-footer-group".to_string(),
241            Display::TableHeaderGroup => "table-header-group".to_string(),
242            Display::TableRow => "table-row".to_string(),
243            Display::TableRowGroup => "table-row-group".to_string(),
244            Display::FlowRoot => "flow-root".to_string(),
245            Display::Contents => "contents".to_string(),
246            Display::ListItem => "list-item".to_string(),
247            Display::Hidden => "none".to_string(),
248        }
249    }
250}
251
252impl Position {
253    pub fn to_class_name(&self) -> String {
254        match self {
255            Position::Static => "static".to_string(),
256            Position::Fixed => "fixed".to_string(),
257            Position::Absolute => "absolute".to_string(),
258            Position::Relative => "relative".to_string(),
259            Position::Sticky => "sticky".to_string(),
260        }
261    }
262    
263    pub fn to_css_value(&self) -> String {
264        match self {
265            Position::Static => "static".to_string(),
266            Position::Fixed => "fixed".to_string(),
267            Position::Absolute => "absolute".to_string(),
268            Position::Relative => "relative".to_string(),
269            Position::Sticky => "sticky".to_string(),
270        }
271    }
272}
273
274impl Overflow {
275    pub fn to_class_name(&self) -> String {
276        match self {
277            Overflow::Auto => "auto".to_string(),
278            Overflow::Hidden => "hidden".to_string(),
279            Overflow::Clip => "clip".to_string(),
280            Overflow::Visible => "visible".to_string(),
281            Overflow::Scroll => "scroll".to_string(),
282        }
283    }
284    
285    pub fn to_css_value(&self) -> String {
286        match self {
287            Overflow::Auto => "auto".to_string(),
288            Overflow::Hidden => "hidden".to_string(),
289            Overflow::Clip => "clip".to_string(),
290            Overflow::Visible => "visible".to_string(),
291            Overflow::Scroll => "scroll".to_string(),
292        }
293    }
294}
295
296impl ZIndex {
297    pub fn to_class_name(&self) -> String {
298        match self {
299            ZIndex::Auto => "auto".to_string(),
300            ZIndex::Zero => "0".to_string(),
301            ZIndex::Ten => "10".to_string(),
302            ZIndex::Twenty => "20".to_string(),
303            ZIndex::Thirty => "30".to_string(),
304            ZIndex::Forty => "40".to_string(),
305            ZIndex::Fifty => "50".to_string(),
306        }
307    }
308    
309    pub fn to_css_value(&self) -> String {
310        match self {
311            ZIndex::Auto => "auto".to_string(),
312            ZIndex::Zero => "0".to_string(),
313            ZIndex::Ten => "10".to_string(),
314            ZIndex::Twenty => "20".to_string(),
315            ZIndex::Thirty => "30".to_string(),
316            ZIndex::Forty => "40".to_string(),
317            ZIndex::Fifty => "50".to_string(),
318        }
319    }
320}
321
322impl Float {
323    pub fn to_class_name(&self) -> String {
324        match self {
325            Float::Right => "right".to_string(),
326            Float::Left => "left".to_string(),
327            Float::None => "none".to_string(),
328        }
329    }
330    
331    pub fn to_css_value(&self) -> String {
332        match self {
333            Float::Right => "right".to_string(),
334            Float::Left => "left".to_string(),
335            Float::None => "none".to_string(),
336        }
337    }
338}
339
340impl Clear {
341    pub fn to_class_name(&self) -> String {
342        match self {
343            Clear::Left => "left".to_string(),
344            Clear::Right => "right".to_string(),
345            Clear::Both => "both".to_string(),
346            Clear::None => "none".to_string(),
347        }
348    }
349    
350    pub fn to_css_value(&self) -> String {
351        match self {
352            Clear::Left => "left".to_string(),
353            Clear::Right => "right".to_string(),
354            Clear::Both => "both".to_string(),
355            Clear::None => "none".to_string(),
356        }
357    }
358}
359
360impl Isolation {
361    pub fn to_class_name(&self) -> String {
362        match self {
363            Isolation::Isolate => "isolate".to_string(),
364            Isolation::Auto => "auto".to_string(),
365        }
366    }
367    
368    pub fn to_css_value(&self) -> String {
369        match self {
370            Isolation::Isolate => "isolate".to_string(),
371            Isolation::Auto => "auto".to_string(),
372        }
373    }
374}
375
376impl ObjectFit {
377    pub fn to_class_name(&self) -> String {
378        match self {
379            ObjectFit::Contain => "contain".to_string(),
380            ObjectFit::Cover => "cover".to_string(),
381            ObjectFit::Fill => "fill".to_string(),
382            ObjectFit::None => "none".to_string(),
383            ObjectFit::ScaleDown => "scale-down".to_string(),
384        }
385    }
386    
387    pub fn to_css_value(&self) -> String {
388        match self {
389            ObjectFit::Contain => "contain".to_string(),
390            ObjectFit::Cover => "cover".to_string(),
391            ObjectFit::Fill => "fill".to_string(),
392            ObjectFit::None => "none".to_string(),
393            ObjectFit::ScaleDown => "scale-down".to_string(),
394        }
395    }
396}
397
398impl ObjectPosition {
399    pub fn to_class_name(&self) -> String {
400        match self {
401            ObjectPosition::Bottom => "bottom".to_string(),
402            ObjectPosition::Center => "center".to_string(),
403            ObjectPosition::Left => "left".to_string(),
404            ObjectPosition::LeftBottom => "left-bottom".to_string(),
405            ObjectPosition::LeftTop => "left-top".to_string(),
406            ObjectPosition::Right => "right".to_string(),
407            ObjectPosition::RightBottom => "right-bottom".to_string(),
408            ObjectPosition::RightTop => "right-top".to_string(),
409            ObjectPosition::Top => "top".to_string(),
410        }
411    }
412    
413    pub fn to_css_value(&self) -> String {
414        match self {
415            ObjectPosition::Bottom => "bottom".to_string(),
416            ObjectPosition::Center => "center".to_string(),
417            ObjectPosition::Left => "left".to_string(),
418            ObjectPosition::LeftBottom => "left bottom".to_string(),
419            ObjectPosition::LeftTop => "left top".to_string(),
420            ObjectPosition::Right => "right".to_string(),
421            ObjectPosition::RightBottom => "right bottom".to_string(),
422            ObjectPosition::RightTop => "right top".to_string(),
423            ObjectPosition::Top => "top".to_string(),
424        }
425    }
426}
427
428impl OverscrollBehavior {
429    pub fn to_class_name(&self) -> String {
430        match self {
431            OverscrollBehavior::Auto => "auto".to_string(),
432            OverscrollBehavior::Contain => "contain".to_string(),
433            OverscrollBehavior::None => "none".to_string(),
434        }
435    }
436    
437    pub fn to_css_value(&self) -> String {
438        match self {
439            OverscrollBehavior::Auto => "auto".to_string(),
440            OverscrollBehavior::Contain => "contain".to_string(),
441            OverscrollBehavior::None => "none".to_string(),
442        }
443    }
444}
445
446impl Visibility {
447    pub fn to_class_name(&self) -> String {
448        match self {
449            Visibility::Visible => "visible".to_string(),
450            Visibility::Hidden => "invisible".to_string(),
451            Visibility::Collapse => "collapse".to_string(),
452        }
453    }
454    
455    pub fn to_css_value(&self) -> String {
456        match self {
457            Visibility::Visible => "visible".to_string(),
458            Visibility::Hidden => "hidden".to_string(),
459            Visibility::Collapse => "collapse".to_string(),
460        }
461    }
462}
463
464impl fmt::Display for Display {
465    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
466        write!(f, "{}", self.to_class_name())
467    }
468}
469
470impl fmt::Display for Position {
471    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
472        write!(f, "{}", self.to_class_name())
473    }
474}
475
476impl fmt::Display for Overflow {
477    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
478        write!(f, "{}", self.to_class_name())
479    }
480}
481
482impl fmt::Display for ZIndex {
483    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
484        write!(f, "{}", self.to_class_name())
485    }
486}
487
488/// Trait for adding display utilities to a class builder
489pub trait DisplayUtilities {
490    fn display(self, display: Display) -> Self;
491}
492
493impl DisplayUtilities for ClassBuilder {
494    fn display(self, display: Display) -> Self {
495        self.class(display.to_class_name())
496    }
497}
498
499/// Trait for adding position utilities to a class builder
500pub trait PositionUtilities {
501    fn position(self, position: Position) -> Self;
502}
503
504impl PositionUtilities for ClassBuilder {
505    fn position(self, position: Position) -> Self {
506        self.class(position.to_class_name())
507    }
508}
509
510/// Trait for adding overflow utilities to a class builder
511pub trait OverflowUtilities {
512    fn overflow(self, overflow: Overflow) -> Self;
513    fn overflow_x(self, overflow: Overflow) -> Self;
514    fn overflow_y(self, overflow: Overflow) -> Self;
515}
516
517impl OverflowUtilities for ClassBuilder {
518    fn overflow(self, overflow: Overflow) -> Self {
519        self.class(format!("overflow-{}", overflow.to_class_name()))
520    }
521    
522    fn overflow_x(self, overflow: Overflow) -> Self {
523        self.class(format!("overflow-x-{}", overflow.to_class_name()))
524    }
525    
526    fn overflow_y(self, overflow: Overflow) -> Self {
527        self.class(format!("overflow-y-{}", overflow.to_class_name()))
528    }
529}
530
531/// Trait for adding z-index utilities to a class builder
532pub trait ZIndexUtilities {
533    fn z_index(self, z_index: ZIndex) -> Self;
534}
535
536impl ZIndexUtilities for ClassBuilder {
537    fn z_index(self, z_index: ZIndex) -> Self {
538        self.class(format!("z-{}", z_index.to_class_name()))
539    }
540}
541
542/// Trait for adding float utilities to a class builder
543pub trait FloatUtilities {
544    fn float(self, float: Float) -> Self;
545}
546
547impl FloatUtilities for ClassBuilder {
548    fn float(self, float: Float) -> Self {
549        self.class(format!("float-{}", float.to_class_name()))
550    }
551}
552
553/// Trait for adding clear utilities to a class builder
554pub trait ClearUtilities {
555    fn clear(self, clear: Clear) -> Self;
556}
557
558impl ClearUtilities for ClassBuilder {
559    fn clear(self, clear: Clear) -> Self {
560        self.class(format!("clear-{}", clear.to_class_name()))
561    }
562}
563
564/// Trait for adding isolation utilities to a class builder
565pub trait IsolationUtilities {
566    fn isolation(self, isolation: Isolation) -> Self;
567}
568
569impl IsolationUtilities for ClassBuilder {
570    fn isolation(self, isolation: Isolation) -> Self {
571        self.class(format!("isolation-{}", isolation.to_class_name()))
572    }
573}
574
575/// Trait for adding object fit utilities to a class builder
576pub trait ObjectFitUtilities {
577    fn object_fit(self, object_fit: ObjectFit) -> Self;
578}
579
580impl ObjectFitUtilities for ClassBuilder {
581    fn object_fit(self, object_fit: ObjectFit) -> Self {
582        self.class(format!("object-{}", object_fit.to_class_name()))
583    }
584}
585
586/// Trait for adding object position utilities to a class builder
587pub trait ObjectPositionUtilities {
588    fn object_position(self, object_position: ObjectPosition) -> Self;
589}
590
591impl ObjectPositionUtilities for ClassBuilder {
592    fn object_position(self, object_position: ObjectPosition) -> Self {
593        self.class(format!("object-{}", object_position.to_class_name()))
594    }
595}
596
597/// Trait for adding overscroll behavior utilities to a class builder
598pub trait OverscrollBehaviorUtilities {
599    fn overscroll_behavior(self, behavior: OverscrollBehavior) -> Self;
600    fn overscroll_behavior_x(self, behavior: OverscrollBehavior) -> Self;
601    fn overscroll_behavior_y(self, behavior: OverscrollBehavior) -> Self;
602}
603
604impl OverscrollBehaviorUtilities for ClassBuilder {
605    fn overscroll_behavior(self, behavior: OverscrollBehavior) -> Self {
606        self.class(format!("overscroll-{}", behavior.to_class_name()))
607    }
608    
609    fn overscroll_behavior_x(self, behavior: OverscrollBehavior) -> Self {
610        self.class(format!("overscroll-x-{}", behavior.to_class_name()))
611    }
612    
613    fn overscroll_behavior_y(self, behavior: OverscrollBehavior) -> Self {
614        self.class(format!("overscroll-y-{}", behavior.to_class_name()))
615    }
616}
617
618/// Trait for adding visibility utilities to a class builder
619pub trait VisibilityUtilities {
620    fn visibility(self, visibility: Visibility) -> Self;
621}
622
623impl VisibilityUtilities for ClassBuilder {
624    fn visibility(self, visibility: Visibility) -> Self {
625        self.class(visibility.to_class_name())
626    }
627}
628
629#[cfg(test)]
630mod tests {
631    use super::*;
632    
633    #[test]
634    fn test_display_utilities() {
635        let classes = ClassBuilder::new()
636            .display(Display::Block)
637            .display(Display::Flex)
638            .display(Display::Grid)
639            .display(Display::Hidden)
640            .build();
641        
642        let css_classes = classes.to_css_classes();
643        assert!(css_classes.contains("block"));
644        assert!(css_classes.contains("flex"));
645        assert!(css_classes.contains("grid"));
646        assert!(css_classes.contains("hidden"));
647    }
648    
649    #[test]
650    fn test_position_utilities() {
651        let classes = ClassBuilder::new()
652            .position(Position::Static)
653            .position(Position::Relative)
654            .position(Position::Absolute)
655            .position(Position::Fixed)
656            .position(Position::Sticky)
657            .build();
658        
659        let css_classes = classes.to_css_classes();
660        assert!(css_classes.contains("static"));
661        assert!(css_classes.contains("relative"));
662        assert!(css_classes.contains("absolute"));
663        assert!(css_classes.contains("fixed"));
664        assert!(css_classes.contains("sticky"));
665    }
666    
667    #[test]
668    fn test_overflow_utilities() {
669        let classes = ClassBuilder::new()
670            .overflow(Overflow::Auto)
671            .overflow(Overflow::Hidden)
672            .overflow(Overflow::Visible)
673            .overflow(Overflow::Scroll)
674            .overflow_x(Overflow::Hidden)
675            .overflow_y(Overflow::Scroll)
676            .build();
677        
678        let css_classes = classes.to_css_classes();
679        assert!(css_classes.contains("overflow-auto"));
680        assert!(css_classes.contains("overflow-hidden"));
681        assert!(css_classes.contains("overflow-visible"));
682        assert!(css_classes.contains("overflow-scroll"));
683        assert!(css_classes.contains("overflow-x-hidden"));
684        assert!(css_classes.contains("overflow-y-scroll"));
685    }
686    
687    #[test]
688    fn test_z_index_utilities() {
689        let classes = ClassBuilder::new()
690            .z_index(ZIndex::Auto)
691            .z_index(ZIndex::Zero)
692            .z_index(ZIndex::Ten)
693            .z_index(ZIndex::Fifty)
694            .build();
695        
696        let css_classes = classes.to_css_classes();
697        assert!(css_classes.contains("z-auto"));
698        assert!(css_classes.contains("z-0"));
699        assert!(css_classes.contains("z-10"));
700        assert!(css_classes.contains("z-50"));
701    }
702    
703    #[test]
704    fn test_float_utilities() {
705        let classes = ClassBuilder::new()
706            .float(Float::Left)
707            .float(Float::Right)
708            .float(Float::None)
709            .build();
710        
711        let css_classes = classes.to_css_classes();
712        assert!(css_classes.contains("float-left"));
713        assert!(css_classes.contains("float-right"));
714        assert!(css_classes.contains("float-none"));
715    }
716    
717    #[test]
718    fn test_clear_utilities() {
719        let classes = ClassBuilder::new()
720            .clear(Clear::Left)
721            .clear(Clear::Right)
722            .clear(Clear::Both)
723            .clear(Clear::None)
724            .build();
725        
726        let css_classes = classes.to_css_classes();
727        assert!(css_classes.contains("clear-left"));
728        assert!(css_classes.contains("clear-right"));
729        assert!(css_classes.contains("clear-both"));
730        assert!(css_classes.contains("clear-none"));
731    }
732    
733    #[test]
734    fn test_isolation_utilities() {
735        let classes = ClassBuilder::new()
736            .isolation(Isolation::Isolate)
737            .isolation(Isolation::Auto)
738            .build();
739        
740        let css_classes = classes.to_css_classes();
741        assert!(css_classes.contains("isolation-isolate"));
742        assert!(css_classes.contains("isolation-auto"));
743    }
744    
745    #[test]
746    fn test_object_fit_utilities() {
747        let classes = ClassBuilder::new()
748            .object_fit(ObjectFit::Contain)
749            .object_fit(ObjectFit::Cover)
750            .object_fit(ObjectFit::Fill)
751            .object_fit(ObjectFit::None)
752            .object_fit(ObjectFit::ScaleDown)
753            .build();
754        
755        let css_classes = classes.to_css_classes();
756        assert!(css_classes.contains("object-contain"));
757        assert!(css_classes.contains("object-cover"));
758        assert!(css_classes.contains("object-fill"));
759        assert!(css_classes.contains("object-none"));
760        assert!(css_classes.contains("object-scale-down"));
761    }
762    
763    #[test]
764    fn test_object_position_utilities() {
765        let classes = ClassBuilder::new()
766            .object_position(ObjectPosition::Center)
767            .object_position(ObjectPosition::Top)
768            .object_position(ObjectPosition::Bottom)
769            .object_position(ObjectPosition::Left)
770            .object_position(ObjectPosition::Right)
771            .build();
772        
773        let css_classes = classes.to_css_classes();
774        assert!(css_classes.contains("object-center"));
775        assert!(css_classes.contains("object-top"));
776        assert!(css_classes.contains("object-bottom"));
777        assert!(css_classes.contains("object-left"));
778        assert!(css_classes.contains("object-right"));
779    }
780    
781    #[test]
782    fn test_overscroll_behavior_utilities() {
783        let classes = ClassBuilder::new()
784            .overscroll_behavior(OverscrollBehavior::Auto)
785            .overscroll_behavior(OverscrollBehavior::Contain)
786            .overscroll_behavior(OverscrollBehavior::None)
787            .overscroll_behavior_x(OverscrollBehavior::Contain)
788            .overscroll_behavior_y(OverscrollBehavior::None)
789            .build();
790        
791        let css_classes = classes.to_css_classes();
792        assert!(css_classes.contains("overscroll-auto"));
793        assert!(css_classes.contains("overscroll-contain"));
794        assert!(css_classes.contains("overscroll-none"));
795        assert!(css_classes.contains("overscroll-x-contain"));
796        assert!(css_classes.contains("overscroll-y-none"));
797    }
798    
799    #[test]
800    fn test_visibility_utilities() {
801        let classes = ClassBuilder::new()
802            .visibility(Visibility::Visible)
803            .visibility(Visibility::Hidden)
804            .visibility(Visibility::Collapse)
805            .build();
806        
807        let css_classes = classes.to_css_classes();
808        assert!(css_classes.contains("visible"));
809        assert!(css_classes.contains("invisible"));
810        assert!(css_classes.contains("collapse"));
811    }
812    
813    #[test]
814    fn test_complex_layout_combination() {
815        let classes = ClassBuilder::new()
816            .display(Display::Flex)
817            .position(Position::Relative)
818            .overflow(Overflow::Hidden)
819            .z_index(ZIndex::Ten)
820            .float(Float::None)
821            .clear(Clear::Both)
822            .isolation(Isolation::Isolate)
823            .object_fit(ObjectFit::Cover)
824            .object_position(ObjectPosition::Center)
825            .overscroll_behavior(OverscrollBehavior::Contain)
826            .visibility(Visibility::Visible)
827            .build();
828        
829        let css_classes = classes.to_css_classes();
830        assert!(css_classes.contains("flex"));
831        assert!(css_classes.contains("relative"));
832        assert!(css_classes.contains("overflow-hidden"));
833        assert!(css_classes.contains("z-10"));
834        assert!(css_classes.contains("float-none"));
835        assert!(css_classes.contains("clear-both"));
836        assert!(css_classes.contains("isolation-isolate"));
837        assert!(css_classes.contains("object-cover"));
838        assert!(css_classes.contains("object-center"));
839        assert!(css_classes.contains("overscroll-contain"));
840        assert!(css_classes.contains("visible"));
841    }
842}