tailwind_rs_core/responsive/
mod.rs

1//! # Responsive Design System Module
2//!
3//! This module provides a comprehensive responsive design system for tailwind-rs.
4//! It's organized into focused sub-modules for better maintainability:
5//! - `breakpoints` - Breakpoint definitions and utilities
6//! - `states` - State definitions for pseudo-classes
7//! - `responsive_values` - Responsive value handling
8//! - `responsive_config` - Configuration management
9//! - `responsive_builder` - Builder pattern for responsive classes
10//! - `flexbox` - Flexbox-specific responsive utilities
11//! - `grid` - Grid-specific responsive utilities
12
13pub mod breakpoints;
14pub mod states;
15pub mod responsive_values;
16pub mod responsive_config;
17pub mod responsive_builder;
18pub mod flexbox;
19pub mod grid;
20
21// Re-export main types for backward compatibility
22pub use breakpoints::Breakpoint;
23pub use states::State;
24pub use responsive_values::ResponsiveValue;
25pub use responsive_config::{ResponsiveConfig, Responsive};
26pub use responsive_builder::ResponsiveBuilder;
27pub use flexbox::{FlexDirection, FlexWrap, JustifyContent, AlignItems, ResponsiveFlex};
28pub use grid::ResponsiveGrid;
29
30/// Create a new responsive configuration with default settings
31pub fn create_responsive_config() -> ResponsiveConfig {
32    ResponsiveConfig::default()
33}
34
35/// Create a new responsive builder
36pub fn create_responsive_builder() -> ResponsiveBuilder {
37    ResponsiveBuilder::default()
38}
39
40/// Create a new responsive flex container
41pub fn create_responsive_flex() -> ResponsiveFlex {
42    ResponsiveFlex::default()
43}
44
45/// Create a new responsive grid container
46pub fn create_responsive_grid() -> ResponsiveGrid {
47    ResponsiveGrid::default()
48}
49
50/// Utility functions for responsive design
51pub mod utils {
52    use super::*;
53    
54    /// Check if a breakpoint is active based on screen width
55    pub fn is_breakpoint_active(breakpoint: Breakpoint, screen_width: u32) -> bool {
56        screen_width >= breakpoint.min_width()
57    }
58    
59    /// Get the appropriate breakpoint for a given screen width
60    pub fn get_breakpoint_for_width(screen_width: u32) -> Breakpoint {
61        if screen_width >= Breakpoint::Xl2.min_width() {
62            Breakpoint::Xl2
63        } else if screen_width >= Breakpoint::Xl.min_width() {
64            Breakpoint::Xl
65        } else if screen_width >= Breakpoint::Lg.min_width() {
66            Breakpoint::Lg
67        } else if screen_width >= Breakpoint::Md.min_width() {
68            Breakpoint::Md
69        } else if screen_width >= Breakpoint::Sm.min_width() {
70            Breakpoint::Sm
71        } else {
72            Breakpoint::Base
73        }
74    }
75    
76    /// Generate responsive classes for a given breakpoint
77    pub fn generate_responsive_classes<T: ToString>(
78        base: T,
79        sm: Option<T>,
80        md: Option<T>,
81        lg: Option<T>,
82        xl: Option<T>,
83        xl2: Option<T>,
84    ) -> String {
85        let mut classes = Vec::new();
86        
87        classes.push(base.to_string());
88        
89        if let Some(sm_val) = sm {
90            classes.push(format!("sm:{}", sm_val.to_string()));
91        }
92        if let Some(md_val) = md {
93            classes.push(format!("md:{}", md_val.to_string()));
94        }
95        if let Some(lg_val) = lg {
96            classes.push(format!("lg:{}", lg_val.to_string()));
97        }
98        if let Some(xl_val) = xl {
99            classes.push(format!("xl:{}", xl_val.to_string()));
100        }
101        if let Some(xl2_val) = xl2 {
102            classes.push(format!("2xl:{}", xl2_val.to_string()));
103        }
104        
105        classes.join(" ")
106    }
107}
108
109#[cfg(test)]
110mod tests {
111    use super::*;
112
113    #[test]
114    fn test_create_responsive_config() {
115        let config = create_responsive_config();
116        assert_eq!(config.breakpoints.len(), 6); // Base, Sm, Md, Lg, Xl, Xl2
117    }
118
119    #[test]
120    fn test_create_responsive_builder() {
121        let builder = create_responsive_builder();
122        assert!(builder.is_empty());
123    }
124
125    #[test]
126    fn test_create_responsive_flex() {
127        let flex = create_responsive_flex();
128        assert_eq!(flex.direction.get_breakpoint(Breakpoint::Base), Some(&FlexDirection::Row));
129    }
130
131    #[test]
132    fn test_create_responsive_grid() {
133        let grid = create_responsive_grid();
134        assert_eq!(grid.columns.get(&Breakpoint::Base), Some(&1));
135    }
136
137    #[test]
138    fn test_is_breakpoint_active() {
139        assert!(utils::is_breakpoint_active(Breakpoint::Base, 0));
140        assert!(utils::is_breakpoint_active(Breakpoint::Sm, 640));
141        assert!(utils::is_breakpoint_active(Breakpoint::Md, 768));
142        assert!(!utils::is_breakpoint_active(Breakpoint::Sm, 639));
143    }
144
145    #[test]
146    fn test_get_breakpoint_for_width() {
147        assert_eq!(utils::get_breakpoint_for_width(0), Breakpoint::Base);
148        assert_eq!(utils::get_breakpoint_for_width(640), Breakpoint::Sm);
149        assert_eq!(utils::get_breakpoint_for_width(768), Breakpoint::Md);
150        assert_eq!(utils::get_breakpoint_for_width(1024), Breakpoint::Lg);
151        assert_eq!(utils::get_breakpoint_for_width(1280), Breakpoint::Xl);
152        assert_eq!(utils::get_breakpoint_for_width(1536), Breakpoint::Xl2);
153    }
154
155    #[test]
156    fn test_generate_responsive_classes() {
157        let classes = utils::generate_responsive_classes(
158            "text-sm",
159            Some("text-base"),
160            Some("text-lg"),
161            Some("text-xl"),
162            None,
163            None,
164        );
165        
166        assert!(classes.contains("text-sm"));
167        assert!(classes.contains("sm:text-base"));
168        assert!(classes.contains("md:text-lg"));
169        assert!(classes.contains("lg:text-xl"));
170        assert!(!classes.contains("xl:"));
171        assert!(!classes.contains("2xl:"));
172    }
173}