@@ -3,8 +3,9 @@ use crate::extract_style::extract_dynamic_style::ExtractDynamicStyle;
33use crate :: extract_style:: extract_static_style:: ExtractStaticStyle ;
44use crate :: extract_style:: extract_style_value:: ExtractStyleValue ;
55use crate :: stylex:: {
6- SelectorPart , decompose_value_conditions, format_number, is_first_that_works_call,
7- is_types_call, is_unitless_property, normalize_stylex_property,
6+ SelectorPart , StylexIncludeRef , decompose_value_conditions, format_number,
7+ is_first_that_works_call, is_include_call_static, is_types_call, is_unitless_property,
8+ normalize_stylex_property,
89} ;
910use crate :: utils:: { get_number_by_literal_expression, get_string_by_literal_expression} ;
1011use css:: optimize_value:: optimize_value;
@@ -19,7 +20,7 @@ use crate::utils::get_string_by_property_key;
1920///
2021/// Handles static string/number values (Phase 1) and value-level conditions (Phase 2).
2122///
22- /// Returns a Vec of `(namespace_name, style_props)` pairs . Each namespace
23+ /// Returns a Vec of `(namespace_name, style_props, css_vars, include_refs )` tuples . Each namespace
2324/// corresponds to a top-level key in the `stylex.create({...})` argument.
2425#[ allow( clippy:: type_complexity) ]
2526pub fn extract_stylex_namespace_styles < ' a > (
@@ -30,6 +31,7 @@ pub fn extract_stylex_namespace_styles<'a>(
3031 String ,
3132 Vec < ExtractStyleProp < ' a > > ,
3233 Option < Vec < ( usize , String ) > > ,
34+ Vec < StylexIncludeRef > ,
3335) > {
3436 let Expression :: ObjectExpression ( obj) = expression else {
3537 return vec ! [ ] ;
@@ -63,25 +65,41 @@ pub fn extract_stylex_namespace_styles<'a>(
6365 if let Some ( ( styles, css_vars) ) =
6466 extract_stylex_dynamic_namespace ( arrow, keyframe_names)
6567 {
66- result. push ( ( ns_name, styles, Some ( css_vars) ) ) ;
68+ result. push ( ( ns_name, styles, Some ( css_vars) , vec ! [ ] ) ) ;
6769 } else {
68- result. push ( ( ns_name, vec ! [ ] , None ) ) ;
70+ result. push ( ( ns_name, vec ! [ ] , None , vec ! [ ] ) ) ;
6971 }
7072 continue ;
7173 }
7274
7375 let Expression :: ObjectExpression ( ns_obj) = & prop. value else {
7476 // Non-object namespace value (e.g., null): push empty styles
75- result. push ( ( ns_name, vec ! [ ] , None ) ) ;
77+ result. push ( ( ns_name, vec ! [ ] , None , vec ! [ ] ) ) ;
7678 continue ;
7779 } ;
7880
7981 let mut styles = vec ! [ ] ;
82+ let mut include_refs = vec ! [ ] ;
8083
8184 for style_prop in ns_obj. properties . iter ( ) {
8285 let ObjectPropertyKind :: ObjectProperty ( style_prop) = style_prop else {
83- // Phase 4c: Spread not supported in style properties
84- if matches ! ( style_prop, ObjectPropertyKind :: SpreadProperty ( _) ) {
86+ // Check for stylex.include() spread
87+ if let ObjectPropertyKind :: SpreadProperty ( spread) = style_prop
88+ && let Expression :: CallExpression ( call) = & spread. argument
89+ && is_include_call_static ( & call. callee )
90+ && !call. arguments . is_empty ( )
91+ {
92+ // Parse include(base.member)
93+ if let Expression :: StaticMemberExpression ( member) =
94+ call. arguments [ 0 ] . to_expression ( )
95+ && let Expression :: Identifier ( ident) = & member. object
96+ {
97+ include_refs. push ( StylexIncludeRef {
98+ var_name : ident. name . to_string ( ) ,
99+ member_name : member. property . name . to_string ( ) ,
100+ } ) ;
101+ }
102+ } else if matches ! ( style_prop, ObjectPropertyKind :: SpreadProperty ( _) ) {
85103 eprintln ! (
86104 "[stylex] ERROR: Object spread is not allowed in stylex.create() namespaces. Define all properties explicitly."
87105 ) ;
@@ -299,7 +317,7 @@ pub fn extract_stylex_namespace_styles<'a>(
299317 ) ) ) ;
300318 }
301319
302- result. push ( ( ns_name, styles, None ) ) ;
320+ result. push ( ( ns_name, styles, None , include_refs ) ) ;
303321 }
304322
305323 result
0 commit comments