@mgcrea/react-native-tailwind 0.9.1 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/README.md +386 -43
  2. package/dist/babel/config-loader.d.ts +12 -3
  3. package/dist/babel/config-loader.test.ts +154 -0
  4. package/dist/babel/config-loader.ts +41 -9
  5. package/dist/babel/index.cjs +592 -69
  6. package/dist/babel/plugin.d.ts +23 -1
  7. package/dist/babel/plugin.test.ts +331 -0
  8. package/dist/babel/plugin.ts +268 -37
  9. package/dist/babel/utils/colorSchemeModifierProcessing.d.ts +34 -0
  10. package/dist/babel/utils/colorSchemeModifierProcessing.ts +89 -0
  11. package/dist/babel/utils/dynamicProcessing.d.ts +34 -3
  12. package/dist/babel/utils/dynamicProcessing.ts +358 -39
  13. package/dist/babel/utils/modifierProcessing.d.ts +3 -3
  14. package/dist/babel/utils/modifierProcessing.ts +5 -5
  15. package/dist/babel/utils/platformModifierProcessing.d.ts +3 -3
  16. package/dist/babel/utils/platformModifierProcessing.ts +4 -4
  17. package/dist/babel/utils/styleInjection.d.ts +13 -0
  18. package/dist/babel/utils/styleInjection.ts +101 -0
  19. package/dist/babel/utils/styleTransforms.test.ts +56 -0
  20. package/dist/babel/utils/twProcessing.d.ts +5 -3
  21. package/dist/babel/utils/twProcessing.ts +27 -6
  22. package/dist/parser/index.d.ts +13 -6
  23. package/dist/parser/index.js +1 -1
  24. package/dist/parser/modifiers.d.ts +48 -2
  25. package/dist/parser/modifiers.js +1 -1
  26. package/dist/parser/modifiers.test.js +1 -1
  27. package/dist/parser/typography.d.ts +3 -1
  28. package/dist/parser/typography.js +1 -1
  29. package/dist/runtime.cjs +1 -1
  30. package/dist/runtime.cjs.map +3 -3
  31. package/dist/runtime.d.ts +8 -1
  32. package/dist/runtime.js +1 -1
  33. package/dist/runtime.js.map +3 -3
  34. package/dist/runtime.test.js +1 -1
  35. package/dist/types/config.d.ts +7 -0
  36. package/dist/types/config.js +0 -0
  37. package/package.json +3 -2
  38. package/src/babel/config-loader.test.ts +154 -0
  39. package/src/babel/config-loader.ts +41 -9
  40. package/src/babel/plugin.test.ts +331 -0
  41. package/src/babel/plugin.ts +268 -37
  42. package/src/babel/utils/colorSchemeModifierProcessing.ts +89 -0
  43. package/src/babel/utils/dynamicProcessing.ts +358 -39
  44. package/src/babel/utils/modifierProcessing.ts +5 -5
  45. package/src/babel/utils/platformModifierProcessing.ts +4 -4
  46. package/src/babel/utils/styleInjection.ts +101 -0
  47. package/src/babel/utils/styleTransforms.test.ts +56 -0
  48. package/src/babel/utils/twProcessing.ts +27 -6
  49. package/src/parser/index.ts +28 -9
  50. package/src/parser/modifiers.test.ts +151 -1
  51. package/src/parser/modifiers.ts +139 -4
  52. package/src/parser/typography.ts +14 -2
  53. package/src/runtime.test.ts +7 -7
  54. package/src/runtime.ts +37 -14
  55. package/src/types/config.ts +7 -0
@@ -2,7 +2,10 @@
2
2
  * Utility functions for processing dynamic className expressions
3
3
  */
4
4
 
5
+ import type { NodePath } from "@babel/core";
5
6
  import type * as BabelTypes from "@babel/types";
7
+ import type { CustomTheme, ParsedModifier } from "../../parser/index.js";
8
+ import type { SchemeModifierConfig } from "../../types/config.js";
6
9
  import type { StyleObject } from "../../types/core.js";
7
10
 
8
11
  /**
@@ -11,10 +14,60 @@ import type { StyleObject } from "../../types/core.js";
11
14
  // eslint-disable-next-line @typescript-eslint/consistent-type-definitions
12
15
  export interface DynamicProcessingState {
13
16
  styleRegistry: Map<string, StyleObject>;
14
- customColors: Record<string, string>;
17
+ customTheme: CustomTheme;
18
+ schemeModifierConfig: SchemeModifierConfig;
15
19
  stylesIdentifier: string;
20
+ needsPlatformImport: boolean;
21
+ needsColorSchemeImport: boolean;
22
+ colorSchemeVariableName: string;
23
+ functionComponentsNeedingColorScheme: Set<NodePath<BabelTypes.Function>>;
16
24
  }
17
25
 
26
+ /**
27
+ * Type for the splitModifierClasses function
28
+ */
29
+ export type SplitModifierClassesFn = (className: string) => {
30
+ baseClasses: string[];
31
+ modifierClasses: ParsedModifier[];
32
+ };
33
+
34
+ /**
35
+ * Type for the processPlatformModifiers function
36
+ */
37
+ export type ProcessPlatformModifiersFn = (
38
+ modifiers: ParsedModifier[],
39
+ state: DynamicProcessingState,
40
+ parseClassName: (className: string, customTheme?: CustomTheme) => StyleObject,
41
+ generateStyleKey: (className: string) => string,
42
+ t: typeof BabelTypes,
43
+ ) => BabelTypes.Expression;
44
+
45
+ /**
46
+ * Type for the processColorSchemeModifiers function
47
+ */
48
+ export type ProcessColorSchemeModifiersFn = (
49
+ modifiers: ParsedModifier[],
50
+ state: DynamicProcessingState,
51
+ parseClassName: (className: string, customTheme?: CustomTheme) => StyleObject,
52
+ generateStyleKey: (className: string) => string,
53
+ t: typeof BabelTypes,
54
+ ) => BabelTypes.Expression[];
55
+
56
+ /**
57
+ * Type for modifier type guard functions
58
+ */
59
+ export type ModifierTypeGuardFn = (modifier: unknown) => boolean;
60
+
61
+ /**
62
+ * Type for the expandSchemeModifier function
63
+ */
64
+ export type ExpandSchemeModifierFn = (
65
+ modifier: ParsedModifier,
66
+ customColors: Record<string, string>,
67
+ darkSuffix: string,
68
+ lightSuffix: string,
69
+ ) => ParsedModifier[];
70
+
18
71
  /**
19
72
  * Result of processing a dynamic expression
20
73
  */
@@ -32,23 +85,73 @@ export type DynamicExpressionResult = {
32
85
  export function processDynamicExpression(
33
86
  expression: BabelTypes.Expression,
34
87
  state: DynamicProcessingState,
35
- parseClassName: (className: string, customColors: Record<string, string>) => StyleObject,
88
+ parseClassName: (className: string, customTheme?: CustomTheme) => StyleObject,
36
89
  generateStyleKey: (className: string) => string,
90
+ splitModifierClasses: SplitModifierClassesFn,
91
+ processPlatformModifiers: ProcessPlatformModifiersFn,
92
+ processColorSchemeModifiers: ProcessColorSchemeModifiersFn,
93
+ componentScope: NodePath<BabelTypes.Function> | null,
94
+ isPlatformModifier: ModifierTypeGuardFn,
95
+ isColorSchemeModifier: ModifierTypeGuardFn,
96
+ isSchemeModifier: ModifierTypeGuardFn,
97
+ expandSchemeModifier: ExpandSchemeModifierFn,
37
98
  t: typeof BabelTypes,
38
99
  ) {
39
100
  // Handle template literals: `m-4 ${condition ? "p-4" : "p-2"}`
40
101
  if (t.isTemplateLiteral(expression)) {
41
- return processTemplateLiteral(expression, state, parseClassName, generateStyleKey, t);
102
+ return processTemplateLiteral(
103
+ expression,
104
+ state,
105
+ parseClassName,
106
+ generateStyleKey,
107
+ splitModifierClasses,
108
+ processPlatformModifiers,
109
+ processColorSchemeModifiers,
110
+ componentScope,
111
+ isPlatformModifier,
112
+ isColorSchemeModifier,
113
+ isSchemeModifier,
114
+ expandSchemeModifier,
115
+ t,
116
+ );
42
117
  }
43
118
 
44
119
  // Handle conditional expressions: condition ? "m-4" : "p-2"
45
120
  if (t.isConditionalExpression(expression)) {
46
- return processConditionalExpression(expression, state, parseClassName, generateStyleKey, t);
121
+ return processConditionalExpression(
122
+ expression,
123
+ state,
124
+ parseClassName,
125
+ generateStyleKey,
126
+ splitModifierClasses,
127
+ processPlatformModifiers,
128
+ processColorSchemeModifiers,
129
+ componentScope,
130
+ isPlatformModifier,
131
+ isColorSchemeModifier,
132
+ isSchemeModifier,
133
+ expandSchemeModifier,
134
+ t,
135
+ );
47
136
  }
48
137
 
49
138
  // Handle logical expressions: condition && "m-4"
50
139
  if (t.isLogicalExpression(expression)) {
51
- return processLogicalExpression(expression, state, parseClassName, generateStyleKey, t);
140
+ return processLogicalExpression(
141
+ expression,
142
+ state,
143
+ parseClassName,
144
+ generateStyleKey,
145
+ splitModifierClasses,
146
+ processPlatformModifiers,
147
+ processColorSchemeModifiers,
148
+ componentScope,
149
+ isPlatformModifier,
150
+ isColorSchemeModifier,
151
+ isSchemeModifier,
152
+ expandSchemeModifier,
153
+ t,
154
+ );
52
155
  }
53
156
 
54
157
  // Unsupported expression type
@@ -61,11 +164,19 @@ export function processDynamicExpression(
61
164
  function processTemplateLiteral(
62
165
  node: BabelTypes.TemplateLiteral,
63
166
  state: DynamicProcessingState,
64
- parseClassName: (className: string, customColors: Record<string, string>) => StyleObject,
167
+ parseClassName: (className: string, customTheme?: CustomTheme) => StyleObject,
65
168
  generateStyleKey: (className: string) => string,
169
+ splitModifierClasses: SplitModifierClassesFn,
170
+ processPlatformModifiers: ProcessPlatformModifiersFn,
171
+ processColorSchemeModifiers: ProcessColorSchemeModifiersFn,
172
+ componentScope: NodePath<BabelTypes.Function> | null,
173
+ isPlatformModifier: ModifierTypeGuardFn,
174
+ isColorSchemeModifier: ModifierTypeGuardFn,
175
+ isSchemeModifier: ModifierTypeGuardFn,
176
+ expandSchemeModifier: ExpandSchemeModifierFn,
66
177
  t: typeof BabelTypes,
67
178
  ) {
68
- const parts: BabelTypes.MemberExpression[] = [];
179
+ const parts: BabelTypes.Expression[] = [];
69
180
  const staticParts: string[] = [];
70
181
 
71
182
  // Process quasis (static parts) and expressions (dynamic parts)
@@ -75,16 +186,31 @@ function processTemplateLiteral(
75
186
 
76
187
  // Add static part if not empty
77
188
  if (staticText) {
78
- // Parse static classes and add to registry
79
- const classes = staticText.split(/\s+/).filter(Boolean);
80
- for (const cls of classes) {
81
- const styleObject = parseClassName(cls, state.customColors);
82
- const styleKey = generateStyleKey(cls);
83
- state.styleRegistry.set(styleKey, styleObject);
84
- staticParts.push(cls);
85
-
86
- // Add to parts array
87
- parts.push(t.memberExpression(t.identifier(state.stylesIdentifier), t.identifier(styleKey)));
189
+ // Parse static classes with modifier support
190
+ const processedExpression = processStringOrExpressionHelper(
191
+ t.stringLiteral(staticText),
192
+ state,
193
+ parseClassName,
194
+ generateStyleKey,
195
+ splitModifierClasses,
196
+ processPlatformModifiers,
197
+ processColorSchemeModifiers,
198
+ componentScope,
199
+ isPlatformModifier,
200
+ isColorSchemeModifier,
201
+ isSchemeModifier,
202
+ expandSchemeModifier,
203
+ t,
204
+ );
205
+
206
+ if (processedExpression) {
207
+ staticParts.push(staticText);
208
+ // Handle array or single expression
209
+ if (t.isArrayExpression(processedExpression)) {
210
+ parts.push(...(processedExpression.elements as BabelTypes.Expression[]));
211
+ } else {
212
+ parts.push(processedExpression);
213
+ }
88
214
  }
89
215
  }
90
216
 
@@ -98,14 +224,21 @@ function processTemplateLiteral(
98
224
  state,
99
225
  parseClassName,
100
226
  generateStyleKey,
227
+ splitModifierClasses,
228
+ processPlatformModifiers,
229
+ processColorSchemeModifiers,
230
+ componentScope,
231
+ isPlatformModifier,
232
+ isColorSchemeModifier,
233
+ isSchemeModifier,
234
+ expandSchemeModifier,
101
235
  t,
102
236
  );
103
237
  if (result) {
104
- parts.push(result.expression as BabelTypes.MemberExpression);
238
+ parts.push(result.expression);
105
239
  } else {
106
240
  // For unsupported expressions, keep them as-is
107
- // This won't work at runtime but maintains the structure
108
- parts.push(expr as BabelTypes.MemberExpression);
241
+ parts.push(expr as BabelTypes.Expression);
109
242
  }
110
243
  }
111
244
  }
@@ -129,12 +262,48 @@ function processTemplateLiteral(
129
262
  function processConditionalExpression(
130
263
  node: BabelTypes.ConditionalExpression,
131
264
  state: DynamicProcessingState,
132
- parseClassName: (className: string, customColors: Record<string, string>) => StyleObject,
265
+ parseClassName: (className: string, customTheme?: CustomTheme) => StyleObject,
133
266
  generateStyleKey: (className: string) => string,
267
+ splitModifierClasses: SplitModifierClassesFn,
268
+ processPlatformModifiers: ProcessPlatformModifiersFn,
269
+ processColorSchemeModifiers: ProcessColorSchemeModifiersFn,
270
+ componentScope: NodePath<BabelTypes.Function> | null,
271
+ isPlatformModifier: ModifierTypeGuardFn,
272
+ isColorSchemeModifier: ModifierTypeGuardFn,
273
+ isSchemeModifier: ModifierTypeGuardFn,
274
+ expandSchemeModifier: ExpandSchemeModifierFn,
134
275
  t: typeof BabelTypes,
135
276
  ) {
136
- const consequent = processStringOrExpression(node.consequent, state, parseClassName, generateStyleKey, t);
137
- const alternate = processStringOrExpression(node.alternate, state, parseClassName, generateStyleKey, t);
277
+ const consequent = processStringOrExpressionHelper(
278
+ node.consequent,
279
+ state,
280
+ parseClassName,
281
+ generateStyleKey,
282
+ splitModifierClasses,
283
+ processPlatformModifiers,
284
+ processColorSchemeModifiers,
285
+ componentScope,
286
+ isPlatformModifier,
287
+ isColorSchemeModifier,
288
+ isSchemeModifier,
289
+ expandSchemeModifier,
290
+ t,
291
+ );
292
+ const alternate = processStringOrExpressionHelper(
293
+ node.alternate,
294
+ state,
295
+ parseClassName,
296
+ generateStyleKey,
297
+ splitModifierClasses,
298
+ processPlatformModifiers,
299
+ processColorSchemeModifiers,
300
+ componentScope,
301
+ isPlatformModifier,
302
+ isColorSchemeModifier,
303
+ isSchemeModifier,
304
+ expandSchemeModifier,
305
+ t,
306
+ );
138
307
 
139
308
  if (!consequent && !alternate) {
140
309
  return null;
@@ -143,8 +312,8 @@ function processConditionalExpression(
143
312
  // Build conditional: condition ? consequentStyle : alternateStyle
144
313
  const expression = t.conditionalExpression(
145
314
  node.test,
146
- (consequent as BabelTypes.Expression) ?? t.nullLiteral(),
147
- (alternate as BabelTypes.Expression) ?? t.nullLiteral(),
315
+ consequent ?? t.nullLiteral(),
316
+ alternate ?? t.nullLiteral(),
148
317
  );
149
318
 
150
319
  return { expression };
@@ -156,8 +325,16 @@ function processConditionalExpression(
156
325
  function processLogicalExpression(
157
326
  node: BabelTypes.LogicalExpression,
158
327
  state: DynamicProcessingState,
159
- parseClassName: (className: string, customColors: Record<string, string>) => StyleObject,
328
+ parseClassName: (className: string, customTheme?: CustomTheme) => StyleObject,
160
329
  generateStyleKey: (className: string) => string,
330
+ splitModifierClasses: SplitModifierClassesFn,
331
+ processPlatformModifiers: ProcessPlatformModifiersFn,
332
+ processColorSchemeModifiers: ProcessColorSchemeModifiersFn,
333
+ componentScope: NodePath<BabelTypes.Function> | null,
334
+ isPlatformModifier: ModifierTypeGuardFn,
335
+ isColorSchemeModifier: ModifierTypeGuardFn,
336
+ isSchemeModifier: ModifierTypeGuardFn,
337
+ expandSchemeModifier: ExpandSchemeModifierFn,
161
338
  t: typeof BabelTypes,
162
339
  ) {
163
340
  // Only handle AND (&&) expressions
@@ -165,28 +342,52 @@ function processLogicalExpression(
165
342
  return null;
166
343
  }
167
344
 
168
- const right = processStringOrExpression(node.right, state, parseClassName, generateStyleKey, t);
345
+ const right = processStringOrExpressionHelper(
346
+ node.right,
347
+ state,
348
+ parseClassName,
349
+ generateStyleKey,
350
+ splitModifierClasses,
351
+ processPlatformModifiers,
352
+ processColorSchemeModifiers,
353
+ componentScope,
354
+ isPlatformModifier,
355
+ isColorSchemeModifier,
356
+ isSchemeModifier,
357
+ expandSchemeModifier,
358
+ t,
359
+ );
169
360
 
170
361
  if (!right) {
171
362
  return null;
172
363
  }
173
364
 
174
365
  // Build logical: condition && style
175
- const expression = t.logicalExpression("&&", node.left, right as BabelTypes.Expression);
366
+ const expression = t.logicalExpression("&&", node.left, right);
176
367
 
177
368
  return { expression };
178
369
  }
179
370
 
180
371
  /**
181
372
  * Process a node that might be a string literal or another expression
373
+ *
374
+ * This helper is called by processStringOrExpression below
182
375
  */
183
- function processStringOrExpression(
376
+ function processStringOrExpressionHelper(
184
377
  node: BabelTypes.StringLiteral | BabelTypes.Expression,
185
378
  state: DynamicProcessingState,
186
- parseClassName: (className: string, customColors: Record<string, string>) => StyleObject,
379
+ parseClassName: (className: string, customTheme?: CustomTheme) => StyleObject,
187
380
  generateStyleKey: (className: string) => string,
381
+ splitModifierClasses: SplitModifierClassesFn,
382
+ processPlatformModifiers: ProcessPlatformModifiersFn,
383
+ processColorSchemeModifiers: ProcessColorSchemeModifiersFn,
384
+ componentScope: NodePath<BabelTypes.Function> | null,
385
+ isPlatformModifier: ModifierTypeGuardFn,
386
+ isColorSchemeModifier: ModifierTypeGuardFn,
387
+ isSchemeModifier: ModifierTypeGuardFn,
388
+ expandSchemeModifier: ExpandSchemeModifierFn,
188
389
  t: typeof BabelTypes,
189
- ) {
390
+ ): BabelTypes.Expression | BabelTypes.ArrayExpression | null {
190
391
  // Handle string literals
191
392
  if (t.isStringLiteral(node)) {
192
393
  const className = node.value.trim();
@@ -194,27 +395,145 @@ function processStringOrExpression(
194
395
  return null;
195
396
  }
196
397
 
197
- // Parse and register styles
198
- const styleObject = parseClassName(className, state.customColors);
199
- const styleKey = generateStyleKey(className);
200
- state.styleRegistry.set(styleKey, styleObject);
398
+ // Split into base and modifier classes
399
+ const { baseClasses, modifierClasses: rawModifierClasses } = splitModifierClasses(className);
400
+
401
+ // Expand scheme: modifiers into dark: and light: modifiers
402
+ const modifierClasses: Array<import("../../parser/index.js").ParsedModifier> = [];
403
+ for (const modifier of rawModifierClasses) {
404
+ if (isSchemeModifier(modifier.modifier)) {
405
+ // Expand scheme: into dark: and light:
406
+ const expanded = expandSchemeModifier(
407
+ modifier,
408
+ state.customTheme.colors ?? {},
409
+ state.schemeModifierConfig.darkSuffix ?? "-dark",
410
+ state.schemeModifierConfig.lightSuffix ?? "-light",
411
+ );
412
+ modifierClasses.push(...expanded);
413
+ } else {
414
+ // Keep other modifiers as-is
415
+ modifierClasses.push(modifier);
416
+ }
417
+ }
418
+
419
+ // Separate modifiers by type
420
+ const platformModifiers = modifierClasses.filter((m) => isPlatformModifier(m.modifier));
421
+ const colorSchemeModifiers = modifierClasses.filter((m) => isColorSchemeModifier(m.modifier));
422
+
423
+ const styleElements: BabelTypes.Expression[] = [];
424
+
425
+ // Process base classes
426
+ if (baseClasses.length > 0) {
427
+ const baseClassName = baseClasses.join(" ");
428
+ const styleObject = parseClassName(baseClassName, state.customTheme);
429
+ const styleKey = generateStyleKey(baseClassName);
430
+ state.styleRegistry.set(styleKey, styleObject);
431
+ styleElements.push(t.memberExpression(t.identifier(state.stylesIdentifier), t.identifier(styleKey)));
432
+ }
433
+
434
+ // Process platform modifiers
435
+ if (platformModifiers.length > 0) {
436
+ state.needsPlatformImport = true;
437
+ const platformExpression = processPlatformModifiers(
438
+ platformModifiers,
439
+ state,
440
+ parseClassName,
441
+ generateStyleKey,
442
+ t,
443
+ );
444
+ styleElements.push(platformExpression);
445
+ }
201
446
 
202
- return t.memberExpression(t.identifier(state.stylesIdentifier), t.identifier(styleKey));
447
+ // Process color scheme modifiers (only if component scope exists)
448
+ if (colorSchemeModifiers.length > 0) {
449
+ if (componentScope) {
450
+ state.needsColorSchemeImport = true;
451
+ state.functionComponentsNeedingColorScheme.add(componentScope);
452
+ const colorSchemeExpressions = processColorSchemeModifiers(
453
+ colorSchemeModifiers,
454
+ state,
455
+ parseClassName,
456
+ generateStyleKey,
457
+ t,
458
+ );
459
+ styleElements.push(...colorSchemeExpressions);
460
+ } else {
461
+ // Warn in development: color scheme modifiers without valid component scope
462
+ // Skip transformation - these modifiers will be ignored
463
+ if (process.env.NODE_ENV !== "production") {
464
+ console.warn(
465
+ "[react-native-tailwind] dark:/light: modifiers in dynamic expressions require a function component scope. " +
466
+ "These modifiers will be ignored.",
467
+ );
468
+ }
469
+ }
470
+ }
471
+
472
+ // Return single element or array
473
+ if (styleElements.length === 0) {
474
+ return null;
475
+ }
476
+ if (styleElements.length === 1) {
477
+ return styleElements[0];
478
+ }
479
+ return t.arrayExpression(styleElements);
203
480
  }
204
481
 
205
482
  // Handle nested expressions recursively
206
483
  if (t.isConditionalExpression(node)) {
207
- const result = processConditionalExpression(node, state, parseClassName, generateStyleKey, t);
484
+ const result = processConditionalExpression(
485
+ node,
486
+ state,
487
+ parseClassName,
488
+ generateStyleKey,
489
+ splitModifierClasses,
490
+ processPlatformModifiers,
491
+ processColorSchemeModifiers,
492
+ componentScope,
493
+ isPlatformModifier,
494
+ isColorSchemeModifier,
495
+ isSchemeModifier,
496
+ expandSchemeModifier,
497
+ t,
498
+ );
208
499
  return result?.expression ?? null;
209
500
  }
210
501
 
211
502
  if (t.isLogicalExpression(node)) {
212
- const result = processLogicalExpression(node, state, parseClassName, generateStyleKey, t);
503
+ const result = processLogicalExpression(
504
+ node,
505
+ state,
506
+ parseClassName,
507
+ generateStyleKey,
508
+ splitModifierClasses,
509
+ processPlatformModifiers,
510
+ processColorSchemeModifiers,
511
+ componentScope,
512
+ isPlatformModifier,
513
+ isColorSchemeModifier,
514
+ isSchemeModifier,
515
+ expandSchemeModifier,
516
+ t,
517
+ );
213
518
  return result?.expression ?? null;
214
519
  }
215
520
 
216
521
  if (t.isTemplateLiteral(node)) {
217
- const result = processTemplateLiteral(node, state, parseClassName, generateStyleKey, t);
522
+ const result = processTemplateLiteral(
523
+ node,
524
+ state,
525
+ parseClassName,
526
+ generateStyleKey,
527
+ splitModifierClasses,
528
+ processPlatformModifiers,
529
+ processColorSchemeModifiers,
530
+ componentScope,
531
+ isPlatformModifier,
532
+ isColorSchemeModifier,
533
+ isSchemeModifier,
534
+ expandSchemeModifier,
535
+ t,
536
+ );
218
537
  return result?.expression ?? null;
219
538
  }
220
539
 
@@ -3,7 +3,7 @@
3
3
  */
4
4
 
5
5
  import type * as BabelTypes from "@babel/types";
6
- import type { ModifierType, ParsedModifier } from "../../parser/index.js";
6
+ import type { CustomTheme, ModifierType, ParsedModifier } from "../../parser/index.js";
7
7
  import type { StyleObject } from "../../types/core.js";
8
8
  import { getStatePropertyForModifier } from "./componentSupport.js";
9
9
 
@@ -13,7 +13,7 @@ import { getStatePropertyForModifier } from "./componentSupport.js";
13
13
  // eslint-disable-next-line @typescript-eslint/consistent-type-definitions
14
14
  export interface ModifierProcessingState {
15
15
  styleRegistry: Map<string, StyleObject>;
16
- customColors: Record<string, string>;
16
+ customTheme: CustomTheme;
17
17
  stylesIdentifier: string;
18
18
  }
19
19
 
@@ -24,7 +24,7 @@ export interface ModifierProcessingState {
24
24
  export function processStaticClassNameWithModifiers(
25
25
  className: string,
26
26
  state: ModifierProcessingState,
27
- parseClassName: (className: string, customColors: Record<string, string>) => StyleObject,
27
+ parseClassName: (className: string, customTheme?: CustomTheme) => StyleObject,
28
28
  generateStyleKey: (className: string) => string,
29
29
  splitModifierClasses: (className: string) => { baseClasses: string[]; modifierClasses: ParsedModifier[] },
30
30
  t: typeof BabelTypes,
@@ -35,7 +35,7 @@ export function processStaticClassNameWithModifiers(
35
35
  let baseStyleExpression: BabelTypes.Node | null = null;
36
36
  if (baseClasses.length > 0) {
37
37
  const baseClassName = baseClasses.join(" ");
38
- const baseStyleObject = parseClassName(baseClassName, state.customColors);
38
+ const baseStyleObject = parseClassName(baseClassName, state.customTheme);
39
39
  const baseStyleKey = generateStyleKey(baseClassName);
40
40
  state.styleRegistry.set(baseStyleKey, baseStyleObject);
41
41
  baseStyleExpression = t.memberExpression(t.identifier(state.stylesIdentifier), t.identifier(baseStyleKey));
@@ -66,7 +66,7 @@ export function processStaticClassNameWithModifiers(
66
66
  for (const [modifierType, modifiers] of modifiersByType) {
67
67
  // Parse all modifier classes together
68
68
  const modifierClassNames = modifiers.map((m) => m.baseClass).join(" ");
69
- const modifierStyleObject = parseClassName(modifierClassNames, state.customColors);
69
+ const modifierStyleObject = parseClassName(modifierClassNames, state.customTheme);
70
70
  const modifierStyleKey = generateStyleKey(`${modifierType}_${modifierClassNames}`);
71
71
  state.styleRegistry.set(modifierStyleKey, modifierStyleObject);
72
72
 
@@ -3,7 +3,7 @@
3
3
  */
4
4
 
5
5
  import type * as BabelTypes from "@babel/types";
6
- import type { ParsedModifier, PlatformModifierType } from "../../parser/index.js";
6
+ import type { CustomTheme, ParsedModifier, PlatformModifierType } from "../../parser/index.js";
7
7
  import type { StyleObject } from "../../types/core.js";
8
8
 
9
9
  /**
@@ -12,7 +12,7 @@ import type { StyleObject } from "../../types/core.js";
12
12
  // eslint-disable-next-line @typescript-eslint/consistent-type-definitions
13
13
  export interface PlatformModifierProcessingState {
14
14
  styleRegistry: Map<string, StyleObject>;
15
- customColors: Record<string, string>;
15
+ customTheme: CustomTheme;
16
16
  stylesIdentifier: string;
17
17
  needsPlatformImport: boolean;
18
18
  }
@@ -34,7 +34,7 @@ export interface PlatformModifierProcessingState {
34
34
  export function processPlatformModifiers(
35
35
  platformModifiers: ParsedModifier[],
36
36
  state: PlatformModifierProcessingState,
37
- parseClassName: (className: string, customColors: Record<string, string>) => StyleObject,
37
+ parseClassName: (className: string, customTheme?: CustomTheme) => StyleObject,
38
38
  generateStyleKey: (className: string) => string,
39
39
  t: typeof BabelTypes,
40
40
  ): BabelTypes.Expression {
@@ -61,7 +61,7 @@ export function processPlatformModifiers(
61
61
  for (const [platform, modifiers] of modifiersByPlatform) {
62
62
  // Parse all classes for this platform together
63
63
  const classNames = modifiers.map((m) => m.baseClass).join(" ");
64
- const styleObject = parseClassName(classNames, state.customColors);
64
+ const styleObject = parseClassName(classNames, state.customTheme);
65
65
  const styleKey = generateStyleKey(`${platform}_${classNames}`);
66
66
 
67
67
  // Register style in the registry