Skip to main content

stylex_transform/transform/fold/
fold_jsx_attr_or_spread.rs

1use swc_core::{
2  common::comments::Comments,
3  ecma::{ast::JSXAttrOrSpread, utils::drop_span, visit::FoldWith},
4};
5
6use crate::StyleXTransform;
7use stylex_ast::ast::factories::{create_jsx_attr_or_spread, create_jsx_spread_attr};
8use stylex_enums::core::TransformationCycle;
9
10impl<C> StyleXTransform<C>
11where
12  C: Comments,
13{
14  pub(crate) fn fold_jsx_attr_or_spreads(
15    &mut self,
16    jsx_attrs: Vec<JSXAttrOrSpread>,
17  ) -> Vec<JSXAttrOrSpread> {
18    match self.state.cycle {
19      TransformationCycle::Initializing => {
20        for jsx_attr in jsx_attrs.iter() {
21          if let JSXAttrOrSpread::SpreadElement(spread) = jsx_attr {
22            let expr = drop_span(*spread.expr.clone());
23            self
24              .state
25              .jsx_spread_attr_exprs_map
26              .entry(expr)
27              .or_default();
28          }
29        }
30        jsx_attrs.fold_children_with(self)
31      },
32      TransformationCycle::PreCleaning => {
33        let result: Vec<JSXAttrOrSpread> = jsx_attrs
34          .iter()
35          .flat_map(|jsx_attr| {
36            match jsx_attr {
37              JSXAttrOrSpread::SpreadElement(spread) => {
38                let expr = drop_span(*spread.expr.clone());
39                if let Some(updated_exprs) =
40                  self.state.jsx_spread_attr_exprs_map.get(&expr).cloned()
41                {
42                  if updated_exprs.is_empty() {
43                    // If the spread was resolved to nothing, remove it
44                    vec![jsx_attr.clone()]
45                  } else {
46                    // Replace the spread with the updated expressions
47                    updated_exprs
48                  }
49                } else {
50                  // If no replacement found, keep the original spread element
51                  vec![create_jsx_spread_attr(*spread.expr.clone())]
52                }
53              },
54              JSXAttrOrSpread::JSXAttr(attr) => {
55                // Keep regular attributes as-is (wrapped in vec for flat_map)
56                vec![create_jsx_attr_or_spread(attr.clone())]
57              },
58            }
59          })
60          .collect();
61
62        result.fold_children_with(self)
63      },
64      _ => jsx_attrs.fold_children_with(self),
65    }
66  }
67}