Skip to main content

stylex_structures/
stylex_options.rs

1use indexmap::IndexMap;
2use rustc_hash::FxHashMap;
3use serde::Deserialize;
4
5use stylex_constants::constants::common::DEFAULT_INJECT_PATH;
6use stylex_enums::property_validation_mode::PropertyValidationMode;
7use stylex_enums::style_resolution::StyleResolution;
8use stylex_enums::sx_prop_name_param::SxPropNameParam;
9
10use crate::{
11  named_import_source::{ImportSources, RuntimeInjection},
12  stylex_env::{EnvEntry, JSFunction},
13};
14
15#[derive(Deserialize, Clone, Debug)]
16#[serde(rename_all = "camelCase")]
17pub struct StyleXOptionsParams {
18  pub style_resolution: Option<StyleResolution>,
19  pub property_validation_mode: Option<PropertyValidationMode>,
20  pub enable_font_size_px_to_rem: Option<bool>,
21  pub runtime_injection: Option<RuntimeInjection>,
22  pub class_name_prefix: Option<String>,
23  pub defined_stylex_css_variables: Option<FxHashMap<String, String>>,
24  pub import_sources: Option<Vec<ImportSources>>,
25  pub treeshake_compensation: Option<bool>,
26  pub enable_inlined_conditional_merge: Option<bool>,
27  pub enable_media_query_order: Option<bool>,
28  pub enable_logical_styles_polyfill: Option<bool>,
29  pub enable_legacy_value_flipping: Option<bool>,
30  pub enable_ltr_rtl_comments: Option<bool>,
31  pub use_real_file_for_source: Option<bool>,
32  pub dev: Option<bool>,
33  pub test: Option<bool>,
34  pub debug: Option<bool>,
35  pub enable_debug_class_names: Option<bool>,
36  pub enable_debug_data_prop: Option<bool>,
37  pub enable_dev_class_names: Option<bool>,
38  pub enable_minified_keys: Option<bool>,
39  pub inject_stylex_side_effects: Option<bool>,
40  pub aliases: Option<FxHashMap<String, Vec<String>>>,
41  #[serde(rename = "unstable_moduleResolution")]
42  pub unstable_module_resolution: Option<ModuleResolution>,
43  pub sx_prop_name: Option<SxPropNameParam>,
44  #[serde(skip)]
45  pub env: Option<IndexMap<String, EnvEntry>>,
46  #[serde(skip)]
47  pub debug_file_path: Option<JSFunction>,
48}
49
50impl Default for StyleXOptionsParams {
51  fn default() -> Self {
52    StyleXOptionsParams {
53      style_resolution: Some(StyleResolution::PropertySpecificity),
54      property_validation_mode: Some(PropertyValidationMode::Silent),
55      enable_font_size_px_to_rem: Some(false),
56      runtime_injection: Some(RuntimeInjection::Boolean(false)),
57      class_name_prefix: Some("x".to_string()),
58      defined_stylex_css_variables: Some(FxHashMap::default()),
59      import_sources: None,
60      treeshake_compensation: Some(true),
61      enable_inlined_conditional_merge: Some(true),
62      enable_media_query_order: Some(true),
63      enable_logical_styles_polyfill: Some(false),
64      enable_ltr_rtl_comments: Some(false),
65      enable_legacy_value_flipping: Some(false),
66      dev: Some(false),
67      test: Some(false),
68      debug: None,
69      enable_debug_class_names: Some(false),
70      enable_debug_data_prop: Some(true),
71      enable_dev_class_names: Some(false),
72      enable_minified_keys: Some(true),
73      inject_stylex_side_effects: Some(false),
74      use_real_file_for_source: Some(true),
75      aliases: None,
76      unstable_module_resolution: None,
77      sx_prop_name: None,
78      env: None,
79      debug_file_path: None,
80    }
81  }
82}
83
84#[derive(Deserialize, Debug, Clone)]
85#[serde(rename_all(deserialize = "camelCase", serialize = "PascalCase"))]
86pub struct ModuleResolution {
87  pub r#type: String,
88  pub root_dir: Option<String>,
89  pub theme_file_extension: Option<String>,
90}
91
92#[derive(Deserialize, Debug, Clone)]
93
94pub enum CheckModuleResolution {
95  CommonJS(ModuleResolution),
96  Haste(ModuleResolution),
97  CrossFileParsing(ModuleResolution),
98}
99
100#[derive(Clone, Debug)]
101pub struct StyleXOptions {
102  pub dev: bool,
103  pub test: bool,
104  pub debug: bool,
105  pub property_validation_mode: PropertyValidationMode,
106  pub enable_debug_class_names: bool,
107  pub enable_debug_data_prop: bool,
108  pub enable_dev_class_names: bool,
109  pub enable_inlined_conditional_merge: bool,
110  pub enable_media_query_order: bool,
111  pub enable_logical_styles_polyfill: bool,
112  pub enable_legacy_value_flipping: bool,
113  pub enable_ltr_rtl_comments: bool,
114  pub enable_minified_keys: bool,
115  pub enable_font_size_px_to_rem: bool,
116  pub use_real_file_for_source: bool,
117  pub class_name_prefix: String,
118  // pub defined_stylex_css_variables: FxHashMap<String, String>,
119  pub style_resolution: StyleResolution,
120  pub runtime_injection: RuntimeInjection,
121  pub import_sources: Vec<ImportSources>,
122  pub treeshake_compensation: bool,
123  pub inject_stylex_side_effects: bool,
124  pub aliases: Option<FxHashMap<String, Vec<String>>>,
125  pub unstable_module_resolution: CheckModuleResolution,
126  pub sx_prop_name: Option<String>,
127  pub env: IndexMap<String, EnvEntry>,
128  pub debug_file_path: Option<JSFunction>,
129}
130
131impl StyleXOptions {
132  pub fn get_haste_module_resolution(root_dir: Option<String>) -> ModuleResolution {
133    ModuleResolution {
134      r#type: "haste".to_string(),
135      root_dir,
136      theme_file_extension: None,
137    }
138  }
139
140  pub fn get_common_js_module_resolution(root_dir: Option<String>) -> ModuleResolution {
141    ModuleResolution {
142      r#type: "commonjs".to_string(),
143      root_dir,
144      theme_file_extension: None,
145    }
146  }
147}
148
149impl Default for StyleXOptions {
150  fn default() -> Self {
151    StyleXOptions {
152      style_resolution: StyleResolution::PropertySpecificity,
153      property_validation_mode: PropertyValidationMode::Silent,
154      enable_font_size_px_to_rem: false,
155      runtime_injection: RuntimeInjection::Boolean(false),
156      class_name_prefix: "x".to_string(),
157      // defined_stylex_css_variables: FxHashMap::default(),
158      import_sources: vec![],
159      dev: false,
160      test: false,
161      debug: false,
162      enable_debug_class_names: false,
163      enable_debug_data_prop: true,
164      enable_dev_class_names: false,
165      enable_inlined_conditional_merge: true,
166      enable_media_query_order: true,
167      enable_logical_styles_polyfill: false,
168      enable_legacy_value_flipping: false,
169      enable_ltr_rtl_comments: false,
170      enable_minified_keys: true,
171      inject_stylex_side_effects: false,
172      use_real_file_for_source: true,
173      treeshake_compensation: false,
174      aliases: None,
175      unstable_module_resolution: CheckModuleResolution::CommonJS(
176        StyleXOptions::get_common_js_module_resolution(None),
177      ),
178      sx_prop_name: Some("sx".to_string()),
179      env: IndexMap::new(),
180      debug_file_path: None,
181    }
182  }
183}
184
185impl From<StyleXOptionsParams> for StyleXOptions {
186  fn from(options: StyleXOptionsParams) -> Self {
187    let module_resolution = options
188      .unstable_module_resolution
189      .unwrap_or_else(|| StyleXOptions::get_common_js_module_resolution(None));
190
191    let unstable_module_resolution = match module_resolution.r#type.to_lowercase().as_str() {
192      "haste" => CheckModuleResolution::Haste(module_resolution),
193      "cross-file-parsing" => CheckModuleResolution::CrossFileParsing(module_resolution),
194      _ => CheckModuleResolution::CommonJS(module_resolution),
195    };
196
197    let runtime_injection = match options.runtime_injection {
198      Some(value) => match value {
199        RuntimeInjection::Boolean(true) => {
200          RuntimeInjection::Regular(DEFAULT_INJECT_PATH.to_string())
201        },
202        RuntimeInjection::Boolean(false) => RuntimeInjection::Boolean(false),
203        RuntimeInjection::Regular(path) => RuntimeInjection::Regular(path),
204        RuntimeInjection::Named(named) => RuntimeInjection::Named(named),
205      },
206      None => RuntimeInjection::Boolean(false),
207    };
208
209    StyleXOptions {
210      style_resolution: options
211        .style_resolution
212        .unwrap_or(StyleResolution::PropertySpecificity),
213      property_validation_mode: options
214        .property_validation_mode
215        .unwrap_or(PropertyValidationMode::Silent),
216      enable_font_size_px_to_rem: options.enable_font_size_px_to_rem.unwrap_or(false),
217      runtime_injection,
218      class_name_prefix: options.class_name_prefix.unwrap_or("x".to_string()),
219      // defined_stylex_css_variables: options.defined_stylex_css_variables.unwrap_or_default(),
220      import_sources: options.import_sources.unwrap_or_else(|| {
221        vec![
222          ImportSources::Regular("stylex".to_string()),
223          ImportSources::Regular("@stylexjs/stylex".to_string()),
224        ]
225      }),
226      dev: options.dev.unwrap_or(false),
227      test: options.test.unwrap_or(false),
228      debug: options.debug.or(options.dev).unwrap_or(false),
229      enable_debug_class_names: options.enable_debug_class_names.unwrap_or(false),
230      enable_debug_data_prop: options.enable_debug_data_prop.unwrap_or(true),
231      enable_dev_class_names: options.enable_dev_class_names.unwrap_or(false),
232      enable_minified_keys: options.enable_minified_keys.unwrap_or(true),
233      inject_stylex_side_effects: options.inject_stylex_side_effects.unwrap_or(false),
234      treeshake_compensation: options.treeshake_compensation.unwrap_or(false),
235      enable_inlined_conditional_merge: options.enable_inlined_conditional_merge.unwrap_or(true),
236      enable_media_query_order: options.enable_media_query_order.unwrap_or(true),
237      enable_logical_styles_polyfill: options.enable_logical_styles_polyfill.unwrap_or(false),
238      enable_legacy_value_flipping: options.enable_legacy_value_flipping.unwrap_or(false),
239      enable_ltr_rtl_comments: options.enable_ltr_rtl_comments.unwrap_or(false),
240      use_real_file_for_source: options.use_real_file_for_source.unwrap_or(true),
241      aliases: options.aliases,
242      unstable_module_resolution,
243      sx_prop_name: match options.sx_prop_name {
244        None => Some("sx".to_string()),
245        Some(SxPropNameParam::Disabled) => None,
246        Some(SxPropNameParam::Enabled(name)) => Some(name),
247      },
248      env: options.env.unwrap_or_default(),
249      debug_file_path: options.debug_file_path,
250    }
251  }
252}