1- use std:: collections:: HashMap ;
1+ use std:: collections:: { BTreeMap , HashMap } ;
22
33pub struct ColorTheme {
44 data : HashMap < String , String > ,
@@ -71,15 +71,15 @@ impl Color {
7171 . map ( Some )
7272 . unwrap_or_else ( || self . themes . keys ( ) . next ( ) ) ;
7373 if let Some ( default_theme_key) = default_theme_key {
74- for ( theme_name, theme_properties) in self . themes . iter ( ) {
74+ let mut entries: Vec < _ > = self . themes . iter ( ) . collect ( ) ;
75+ entries. sort_by_key ( |( k, _) | * k) ;
76+ entries. reverse ( ) ;
77+ for ( theme_name, theme_properties) in entries {
7578 let theme_key = if * theme_name == * default_theme_key {
7679 None
7780 } else {
7881 Some ( theme_name)
7982 } ;
80- if theme_properties. is_empty ( ) {
81- continue ;
82- }
8383 if let Some ( theme_key) = theme_key {
8484 theme_declaration
8585 . push_str ( format ! ( ":root[data-theme={}]{{" , theme_key) . as_str ( ) ) ;
@@ -127,7 +127,7 @@ impl Typography {
127127pub struct Theme {
128128 pub colors : Color ,
129129 pub break_points : Vec < u16 > ,
130- pub typography : HashMap < String , Vec < Typography > > ,
130+ pub typography : BTreeMap < String , Vec < Typography > > ,
131131}
132132
133133impl Default for Theme {
@@ -141,7 +141,7 @@ impl Theme {
141141 Self {
142142 colors : Color :: new ( ) ,
143143 break_points : vec ! [ 0 , 480 , 768 , 992 , 1280 ] ,
144- typography : HashMap :: new ( ) ,
144+ typography : BTreeMap :: new ( ) ,
145145 }
146146 }
147147
@@ -166,6 +166,7 @@ impl Theme {
166166
167167 pub fn to_css ( & self ) -> String {
168168 let mut css = self . colors . to_css ( ) ;
169+ let mut level_map = BTreeMap :: < u8 , Vec < String > > :: new ( ) ;
169170 for ty in self . typography . iter ( ) {
170171 for t in ty. 1 . iter ( ) {
171172 let css_content = format ! (
@@ -195,17 +196,24 @@ impl Theme {
195196 continue ;
196197 }
197198 let typo_css = format ! ( ".typo-{}{{{}}}" , ty. 0 , css_content) ;
198-
199- if t. level == 0 {
200- css. push_str ( typo_css. as_str ( ) ) ;
201- } else {
202- let media = self
203- . break_points
204- . get ( t. level as usize )
205- . map ( |v| format ! ( "(min-width:{}px)" , v) ) ;
206- if let Some ( media) = media {
207- css. push_str ( format ! ( "\n @media {}{{{}}}" , media, typo_css) . as_str ( ) ) ;
208- }
199+ level_map
200+ . get_mut ( & t. level )
201+ . map ( |v| v. push ( typo_css. clone ( ) ) )
202+ . unwrap_or_else ( || {
203+ level_map. insert ( t. level , vec ! [ typo_css. clone( ) ] ) ;
204+ } ) ;
205+ }
206+ }
207+ for ( level, css_vec) in level_map {
208+ if level == 0 {
209+ css. push_str ( css_vec. join ( "" ) . as_str ( ) ) ;
210+ } else {
211+ let media = self
212+ . break_points
213+ . get ( level as usize )
214+ . map ( |v| format ! ( "(min-width:{}px)" , v) ) ;
215+ if let Some ( media) = media {
216+ css. push_str ( format ! ( "\n @media {}{{{}}}" , media, css_vec. join( "" ) ) . as_str ( ) ) ;
209217 }
210218 }
211219 }
@@ -227,6 +235,9 @@ mod tests {
227235 let mut color_theme = ColorTheme :: new ( ) ;
228236 color_theme. add_color ( "primary" . to_string ( ) , "#000" . to_string ( ) ) ;
229237 theme. add_color_theme ( "default" . to_string ( ) , color_theme) ;
238+ let mut color_theme = ColorTheme :: new ( ) ;
239+ color_theme. add_color ( "primary" . to_string ( ) , "#fff" . to_string ( ) ) ;
240+ theme. add_color_theme ( "dark" . to_string ( ) , color_theme) ;
230241 theme. add_typography (
231242 "default" . to_string ( ) ,
232243 vec ! [
@@ -248,10 +259,22 @@ mod tests {
248259 ) ,
249260 ] ,
250261 ) ;
262+
263+ theme. add_typography (
264+ "default1" . to_string ( ) ,
265+ vec ! [ Typography :: new(
266+ Some ( "Arial" . to_string( ) ) ,
267+ Some ( "24px" . to_string( ) ) ,
268+ Some ( "400" . to_string( ) ) ,
269+ Some ( "1.5" . to_string( ) ) ,
270+ Some ( "0.5" . to_string( ) ) ,
271+ 1 ,
272+ ) ] ,
273+ ) ;
251274 let css = theme. to_css ( ) ;
252275 assert_eq ! (
253276 css,
254- ":root{--primary:#000;}\n .typo-default{font-family:Arial;font-size:16px;font-weight:400;line-height:1.5;letter-spacing:0.5}\n @media (min-width:480px){.typo-default{font-family:Arial;font-size:24px;font-weight:400;line-height:1.5;letter-spacing:0.5}}"
277+ ":root{--primary:#000;}\n :root[data-theme=dark]{--primary:#fff;} \n .typo-default{font-family:Arial;font-size:16px;font-weight:400;line-height:1.5;letter-spacing:0.5}\n @media (min-width:480px){.typo-default{font-family:Arial;font-size:24px;font-weight:400;line-height:1.5;letter-spacing:0.5}.typo-default1 {font-family:Arial;font-size:24px;font-weight:400;line-height:1.5;letter-spacing:0.5}}"
255278 ) ;
256279 }
257280}
0 commit comments