11use extractor:: { extract, ExtractOption , ExtractStyleValue , StyleProperty } ;
22use js_sys:: { Object , Reflect } ;
33use once_cell:: sync:: Lazy ;
4- use sheet:: theme:: { ColorTheme , Theme } ;
4+ use sheet:: theme:: { ColorTheme , Theme , Typography } ;
55use sheet:: StyleSheet ;
6+ use std:: collections:: HashSet ;
67use std:: sync:: Mutex ;
78use wasm_bindgen:: prelude:: * ;
89
@@ -69,6 +70,7 @@ impl Output {
6970 collected = true ;
7071 }
7172 }
73+ ExtractStyleValue :: Typography ( _) => { }
7274 }
7375 }
7476 if !collected {
@@ -104,10 +106,31 @@ pub fn code_extract(
104106 Err ( error) => Err ( JsValue :: from_str ( error. to_string ( ) . as_str ( ) ) ) ,
105107 }
106108}
109+ fn object_to_typography ( obj : Object , level : u8 ) -> Result < Typography , JsValue > {
110+ Ok ( Typography :: new (
111+ Reflect :: get ( & obj, & JsValue :: from_str ( "fontFamily" ) ) ?
112+ . as_string ( )
113+ . unwrap ( ) ,
114+ Reflect :: get ( & obj, & JsValue :: from_str ( "fontSize" ) ) ?
115+ . as_string ( )
116+ . unwrap ( ) ,
117+ Reflect :: get ( & obj, & JsValue :: from_str ( "fontWeight" ) ) ?
118+ . as_string ( )
119+ . unwrap ( ) ,
120+ Reflect :: get ( & obj, & JsValue :: from_str ( "lineHeight" ) ) ?
121+ . as_string ( )
122+ . unwrap ( ) ,
123+ Reflect :: get ( & obj, & JsValue :: from_str ( "letterSpacing" ) ) ?
124+ . as_string ( )
125+ . unwrap ( ) ,
126+ level,
127+ ) )
128+ }
129+
107130fn theme_object_to_hashmap ( js_value : JsValue ) -> Result < Theme , JsValue > {
108131 let mut theme = Theme :: new ( ) ;
109132
110- if let Some ( obj) = js_value. dyn_into :: < Object > ( ) . ok ( ) {
133+ if let Ok ( obj) = js_value. dyn_into :: < Object > ( ) {
111134 // get colors
112135 if let Some ( colors_obj) = Reflect :: get ( & obj, & JsValue :: from_str ( "colors" ) )
113136 . ok ( )
@@ -143,6 +166,38 @@ fn theme_object_to_hashmap(js_value: JsValue) -> Result<Theme, JsValue> {
143166 }
144167 }
145168 }
169+
170+ if let Some ( typography_obj) = Reflect :: get ( & obj, & JsValue :: from_str ( "typography" ) )
171+ . ok ( )
172+ . and_then ( |v| v. dyn_into :: < Object > ( ) . ok ( ) )
173+ {
174+ for entry in Object :: entries ( & typography_obj) . into_iter ( ) {
175+ if let ( Ok ( key) , Ok ( value) ) = (
176+ Reflect :: get ( & entry, & JsValue :: from_f64 ( 0f64 ) ) ,
177+ Reflect :: get ( & entry, & JsValue :: from_f64 ( 1f64 ) ) ,
178+ ) {
179+ if let ( Some ( key_str) , Some ( typo_value) ) =
180+ ( key. as_string ( ) , value. dyn_into :: < Object > ( ) . ok ( ) )
181+ {
182+ let mut typo_vec = vec ! [ ] ;
183+ if typo_value. is_array ( ) {
184+ if let Ok ( typo_arr) = typo_value. dyn_into :: < js_sys:: Array > ( ) {
185+ for i in 0 ..typo_arr. length ( ) {
186+ if let Ok ( typo_obj) = typo_arr. get ( i) . dyn_into :: < Object > ( ) {
187+ typo_vec. push ( object_to_typography ( typo_obj, i as u8 ) ?) ;
188+ }
189+ }
190+ }
191+ } else if typo_value. is_object ( ) && !typo_value. is_null ( ) {
192+ if let Ok ( typo_obj) = typo_value. dyn_into :: < Object > ( ) {
193+ typo_vec. push ( object_to_typography ( typo_obj, 0 ) ?) ;
194+ }
195+ }
196+ theme. typography . insert ( key_str, typo_vec) ;
197+ }
198+ }
199+ }
200+ }
146201 } else {
147202 return Err ( JsValue :: from_str (
148203 "Failed to convert the provided object to a hashmap" ,
@@ -161,6 +216,47 @@ pub fn register_theme(theme_object: JsValue) -> Result<(), JsValue> {
161216
162217#[ wasm_bindgen( js_name = "getCss" ) ]
163218pub fn get_css ( ) -> Result < String , JsValue > {
164- let mut sheet = GLOBAL_STYLE_SHEET . lock ( ) . unwrap ( ) ;
219+ let sheet = GLOBAL_STYLE_SHEET . lock ( ) . unwrap ( ) ;
165220 Ok ( sheet. create_css ( ) )
166221}
222+
223+ #[ wasm_bindgen( js_name = "getThemeInterface" ) ]
224+ pub fn get_theme_interface (
225+ package_name : & str ,
226+ color_interface_name : & str ,
227+ typography_interface_name : & str ,
228+ ) -> Result < String , JsValue > {
229+ let sheet = GLOBAL_STYLE_SHEET . lock ( ) . unwrap ( ) ;
230+ let mut color_keys = HashSet :: new ( ) ;
231+ let mut typography_keys = HashSet :: new ( ) ;
232+ for color_theme in sheet. theme . colors . themes . values ( ) {
233+ color_theme. keys ( ) . for_each ( |key| {
234+ color_keys. insert ( key. clone ( ) ) ;
235+ } ) ;
236+ }
237+ sheet. theme . typography . keys ( ) . for_each ( |key| {
238+ typography_keys. insert ( key. clone ( ) ) ;
239+ } ) ;
240+
241+ if color_keys. is_empty ( ) && typography_keys. is_empty ( ) {
242+ Ok ( "" . to_string ( ) )
243+ } else {
244+ Ok ( format ! (
245+ "import \" {}\" ;declare module \" {}\" {{interface {} {{{}}}interface {} {{{}}}}}" ,
246+ package_name,
247+ package_name,
248+ color_interface_name,
249+ color_keys
250+ . into_iter( )
251+ . map( |key| format!( "${}:null;" , key) )
252+ . collect:: <Vec <String >>( )
253+ . join( "" ) ,
254+ typography_interface_name,
255+ typography_keys
256+ . into_iter( )
257+ . map( |key| format!( "{}:null;" , key) )
258+ . collect:: <Vec <String >>( )
259+ . join( "" )
260+ ) )
261+ }
262+ }
0 commit comments