@mgcrea/react-native-tailwind 0.7.0 → 0.8.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 (81) hide show
  1. package/README.md +2 -1
  2. package/dist/babel/index.cjs +333 -195
  3. package/dist/babel/index.d.ts +4 -40
  4. package/dist/babel/index.test.ts +214 -1
  5. package/dist/babel/index.ts +4 -1169
  6. package/dist/babel/plugin.d.ts +42 -0
  7. package/{src/babel/index.test.ts → dist/babel/plugin.test.ts} +216 -2
  8. package/dist/babel/plugin.ts +491 -0
  9. package/dist/babel/utils/attributeMatchers.d.ts +23 -0
  10. package/dist/babel/utils/attributeMatchers.ts +71 -0
  11. package/dist/babel/utils/componentSupport.d.ts +18 -0
  12. package/dist/babel/utils/componentSupport.ts +68 -0
  13. package/dist/babel/utils/dynamicProcessing.d.ts +32 -0
  14. package/dist/babel/utils/dynamicProcessing.ts +223 -0
  15. package/dist/babel/utils/modifierProcessing.d.ts +26 -0
  16. package/dist/babel/utils/modifierProcessing.ts +118 -0
  17. package/dist/babel/utils/styleInjection.d.ts +15 -0
  18. package/dist/babel/utils/styleInjection.ts +80 -0
  19. package/dist/babel/utils/styleTransforms.d.ts +39 -0
  20. package/dist/babel/utils/styleTransforms.test.ts +349 -0
  21. package/dist/babel/utils/styleTransforms.ts +258 -0
  22. package/dist/babel/utils/twProcessing.d.ts +28 -0
  23. package/dist/babel/utils/twProcessing.ts +124 -0
  24. package/dist/components/TextInput.d.ts +171 -14
  25. package/dist/config/tailwind.d.ts +302 -0
  26. package/dist/config/tailwind.js +1 -0
  27. package/dist/index.d.ts +5 -4
  28. package/dist/index.js +1 -1
  29. package/dist/parser/colors.js +1 -1
  30. package/dist/parser/index.d.ts +1 -0
  31. package/dist/parser/index.js +1 -1
  32. package/dist/parser/modifiers.d.ts +2 -2
  33. package/dist/parser/modifiers.js +1 -1
  34. package/dist/parser/placeholder.d.ts +36 -0
  35. package/dist/parser/placeholder.js +1 -0
  36. package/dist/parser/placeholder.test.js +1 -0
  37. package/dist/parser/typography.d.ts +1 -0
  38. package/dist/parser/typography.js +1 -1
  39. package/dist/parser/typography.test.js +1 -1
  40. package/dist/runtime.cjs +1 -1
  41. package/dist/runtime.cjs.map +4 -4
  42. package/dist/runtime.d.ts +1 -14
  43. package/dist/runtime.js +1 -1
  44. package/dist/runtime.js.map +4 -4
  45. package/dist/stubs/tw.d.ts +1 -14
  46. package/dist/types/core.d.ts +40 -0
  47. package/dist/types/core.js +0 -0
  48. package/dist/types/index.d.ts +2 -0
  49. package/dist/types/index.js +1 -0
  50. package/dist/types/runtime.d.ts +15 -0
  51. package/dist/types/runtime.js +1 -0
  52. package/dist/types/util.d.ts +3 -0
  53. package/dist/types/util.js +0 -0
  54. package/package.json +1 -1
  55. package/src/babel/index.ts +4 -1169
  56. package/src/babel/plugin.test.ts +482 -0
  57. package/src/babel/plugin.ts +491 -0
  58. package/src/babel/utils/attributeMatchers.ts +71 -0
  59. package/src/babel/utils/componentSupport.ts +68 -0
  60. package/src/babel/utils/dynamicProcessing.ts +223 -0
  61. package/src/babel/utils/modifierProcessing.ts +118 -0
  62. package/src/babel/utils/styleInjection.ts +80 -0
  63. package/src/babel/utils/styleTransforms.test.ts +349 -0
  64. package/src/babel/utils/styleTransforms.ts +258 -0
  65. package/src/babel/utils/twProcessing.ts +124 -0
  66. package/src/components/TextInput.tsx +17 -14
  67. package/src/config/{palettes.ts → tailwind.ts} +2 -2
  68. package/src/index.ts +6 -3
  69. package/src/parser/colors.ts +2 -2
  70. package/src/parser/index.ts +1 -0
  71. package/src/parser/modifiers.ts +10 -4
  72. package/src/parser/placeholder.test.ts +105 -0
  73. package/src/parser/placeholder.ts +78 -0
  74. package/src/parser/typography.test.ts +11 -0
  75. package/src/parser/typography.ts +20 -2
  76. package/src/runtime.ts +1 -16
  77. package/src/stubs/tw.ts +1 -16
  78. package/src/{types.ts → types/core.ts} +0 -4
  79. package/src/types/index.ts +2 -0
  80. package/src/types/runtime.ts +17 -0
  81. package/src/types/util.ts +1 -0
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Utility functions for processing dynamic className expressions
3
+ */
4
+ import type * as BabelTypes from "@babel/types";
5
+ import type { StyleObject } from "../../types/core.js";
6
+ /**
7
+ * Plugin state interface (subset needed for dynamic processing)
8
+ */
9
+ export interface DynamicProcessingState {
10
+ styleRegistry: Map<string, StyleObject>;
11
+ customColors: Record<string, string>;
12
+ stylesIdentifier: string;
13
+ }
14
+ /**
15
+ * Result of processing a dynamic expression
16
+ */
17
+ export type DynamicExpressionResult = {
18
+ expression: BabelTypes.Expression;
19
+ staticParts?: string[];
20
+ };
21
+ /**
22
+ * Process a dynamic className expression
23
+ * Extracts static strings and transforms the expression to use pre-compiled styles
24
+ */
25
+ export declare function processDynamicExpression(expression: BabelTypes.Expression, state: DynamicProcessingState, parseClassName: (className: string, customColors: Record<string, string>) => StyleObject, generateStyleKey: (className: string) => string, t: typeof BabelTypes): {
26
+ expression: BabelTypes.ArrayExpression | BabelTypes.MemberExpression;
27
+ staticParts: string[] | undefined;
28
+ } | {
29
+ expression: BabelTypes.ConditionalExpression;
30
+ } | {
31
+ expression: BabelTypes.LogicalExpression;
32
+ } | null;
@@ -0,0 +1,223 @@
1
+ /**
2
+ * Utility functions for processing dynamic className expressions
3
+ */
4
+
5
+ import type * as BabelTypes from "@babel/types";
6
+ import type { StyleObject } from "../../types/core.js";
7
+
8
+ /**
9
+ * Plugin state interface (subset needed for dynamic processing)
10
+ */
11
+ // eslint-disable-next-line @typescript-eslint/consistent-type-definitions
12
+ export interface DynamicProcessingState {
13
+ styleRegistry: Map<string, StyleObject>;
14
+ customColors: Record<string, string>;
15
+ stylesIdentifier: string;
16
+ }
17
+
18
+ /**
19
+ * Result of processing a dynamic expression
20
+ */
21
+ export type DynamicExpressionResult = {
22
+ // The transformed expression to use in the style prop
23
+ expression: BabelTypes.Expression;
24
+ // Static parts that can be parsed at compile time (if any)
25
+ staticParts?: string[];
26
+ };
27
+
28
+ /**
29
+ * Process a dynamic className expression
30
+ * Extracts static strings and transforms the expression to use pre-compiled styles
31
+ */
32
+ export function processDynamicExpression(
33
+ expression: BabelTypes.Expression,
34
+ state: DynamicProcessingState,
35
+ parseClassName: (className: string, customColors: Record<string, string>) => StyleObject,
36
+ generateStyleKey: (className: string) => string,
37
+ t: typeof BabelTypes,
38
+ ) {
39
+ // Handle template literals: `m-4 ${condition ? "p-4" : "p-2"}`
40
+ if (t.isTemplateLiteral(expression)) {
41
+ return processTemplateLiteral(expression, state, parseClassName, generateStyleKey, t);
42
+ }
43
+
44
+ // Handle conditional expressions: condition ? "m-4" : "p-2"
45
+ if (t.isConditionalExpression(expression)) {
46
+ return processConditionalExpression(expression, state, parseClassName, generateStyleKey, t);
47
+ }
48
+
49
+ // Handle logical expressions: condition && "m-4"
50
+ if (t.isLogicalExpression(expression)) {
51
+ return processLogicalExpression(expression, state, parseClassName, generateStyleKey, t);
52
+ }
53
+
54
+ // Unsupported expression type
55
+ return null;
56
+ }
57
+
58
+ /**
59
+ * Process template literal: `static ${dynamic} more-static`
60
+ */
61
+ function processTemplateLiteral(
62
+ node: BabelTypes.TemplateLiteral,
63
+ state: DynamicProcessingState,
64
+ parseClassName: (className: string, customColors: Record<string, string>) => StyleObject,
65
+ generateStyleKey: (className: string) => string,
66
+ t: typeof BabelTypes,
67
+ ) {
68
+ const parts: BabelTypes.MemberExpression[] = [];
69
+ const staticParts: string[] = [];
70
+
71
+ // Process quasis (static parts) and expressions (dynamic parts)
72
+ for (let i = 0; i < node.quasis.length; i++) {
73
+ const quasi = node.quasis[i];
74
+ const staticText = quasi.value.cooked?.trim();
75
+
76
+ // Add static part if not empty
77
+ 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)));
88
+ }
89
+ }
90
+
91
+ // Add dynamic expression if exists
92
+ if (i < node.expressions.length) {
93
+ const expr = node.expressions[i];
94
+
95
+ // Recursively process nested dynamic expressions
96
+ const result = processDynamicExpression(
97
+ expr as BabelTypes.Expression,
98
+ state,
99
+ parseClassName,
100
+ generateStyleKey,
101
+ t,
102
+ );
103
+ if (result) {
104
+ parts.push(result.expression as BabelTypes.MemberExpression);
105
+ } else {
106
+ // 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);
109
+ }
110
+ }
111
+ }
112
+
113
+ if (parts.length === 0) {
114
+ return null;
115
+ }
116
+
117
+ // If single part, return it directly; otherwise return array
118
+ const expression = parts.length === 1 ? parts[0] : t.arrayExpression(parts);
119
+
120
+ return {
121
+ expression,
122
+ staticParts: staticParts.length > 0 ? staticParts : undefined,
123
+ };
124
+ }
125
+
126
+ /**
127
+ * Process conditional expression: condition ? "class-a" : "class-b"
128
+ */
129
+ function processConditionalExpression(
130
+ node: BabelTypes.ConditionalExpression,
131
+ state: DynamicProcessingState,
132
+ parseClassName: (className: string, customColors: Record<string, string>) => StyleObject,
133
+ generateStyleKey: (className: string) => string,
134
+ t: typeof BabelTypes,
135
+ ) {
136
+ const consequent = processStringOrExpression(node.consequent, state, parseClassName, generateStyleKey, t);
137
+ const alternate = processStringOrExpression(node.alternate, state, parseClassName, generateStyleKey, t);
138
+
139
+ if (!consequent && !alternate) {
140
+ return null;
141
+ }
142
+
143
+ // Build conditional: condition ? consequentStyle : alternateStyle
144
+ const expression = t.conditionalExpression(
145
+ node.test,
146
+ (consequent as BabelTypes.Expression) ?? t.nullLiteral(),
147
+ (alternate as BabelTypes.Expression) ?? t.nullLiteral(),
148
+ );
149
+
150
+ return { expression };
151
+ }
152
+
153
+ /**
154
+ * Process logical expression: condition && "class-a"
155
+ */
156
+ function processLogicalExpression(
157
+ node: BabelTypes.LogicalExpression,
158
+ state: DynamicProcessingState,
159
+ parseClassName: (className: string, customColors: Record<string, string>) => StyleObject,
160
+ generateStyleKey: (className: string) => string,
161
+ t: typeof BabelTypes,
162
+ ) {
163
+ // Only handle AND (&&) expressions
164
+ if (node.operator !== "&&") {
165
+ return null;
166
+ }
167
+
168
+ const right = processStringOrExpression(node.right, state, parseClassName, generateStyleKey, t);
169
+
170
+ if (!right) {
171
+ return null;
172
+ }
173
+
174
+ // Build logical: condition && style
175
+ const expression = t.logicalExpression("&&", node.left, right as BabelTypes.Expression);
176
+
177
+ return { expression };
178
+ }
179
+
180
+ /**
181
+ * Process a node that might be a string literal or another expression
182
+ */
183
+ function processStringOrExpression(
184
+ node: BabelTypes.StringLiteral | BabelTypes.Expression,
185
+ state: DynamicProcessingState,
186
+ parseClassName: (className: string, customColors: Record<string, string>) => StyleObject,
187
+ generateStyleKey: (className: string) => string,
188
+ t: typeof BabelTypes,
189
+ ) {
190
+ // Handle string literals
191
+ if (t.isStringLiteral(node)) {
192
+ const className = node.value.trim();
193
+ if (!className) {
194
+ return null;
195
+ }
196
+
197
+ // Parse and register styles
198
+ const styleObject = parseClassName(className, state.customColors);
199
+ const styleKey = generateStyleKey(className);
200
+ state.styleRegistry.set(styleKey, styleObject);
201
+
202
+ return t.memberExpression(t.identifier(state.stylesIdentifier), t.identifier(styleKey));
203
+ }
204
+
205
+ // Handle nested expressions recursively
206
+ if (t.isConditionalExpression(node)) {
207
+ const result = processConditionalExpression(node, state, parseClassName, generateStyleKey, t);
208
+ return result?.expression ?? null;
209
+ }
210
+
211
+ if (t.isLogicalExpression(node)) {
212
+ const result = processLogicalExpression(node, state, parseClassName, generateStyleKey, t);
213
+ return result?.expression ?? null;
214
+ }
215
+
216
+ if (t.isTemplateLiteral(node)) {
217
+ const result = processTemplateLiteral(node, state, parseClassName, generateStyleKey, t);
218
+ return result?.expression ?? null;
219
+ }
220
+
221
+ // Unsupported - return null
222
+ return null;
223
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Utility functions for processing class modifiers (active:, hover:, focus:, etc.)
3
+ */
4
+ import type * as BabelTypes from "@babel/types";
5
+ import type { ModifierType, ParsedModifier } from "../../parser/index.js";
6
+ import type { StyleObject } from "../../types/core.js";
7
+ /**
8
+ * Plugin state interface (subset needed for modifier processing)
9
+ */
10
+ export interface ModifierProcessingState {
11
+ styleRegistry: Map<string, StyleObject>;
12
+ customColors: Record<string, string>;
13
+ stylesIdentifier: string;
14
+ }
15
+ /**
16
+ * Process a static className string that contains modifiers
17
+ * Returns a style function expression for Pressable components
18
+ */
19
+ export declare function processStaticClassNameWithModifiers(className: string, state: ModifierProcessingState, parseClassName: (className: string, customColors: Record<string, string>) => StyleObject, generateStyleKey: (className: string) => string, splitModifierClasses: (className: string) => {
20
+ baseClasses: string[];
21
+ modifierClasses: ParsedModifier[];
22
+ }, t: typeof BabelTypes): BabelTypes.Expression;
23
+ /**
24
+ * Create a style function for Pressable: ({ pressed }) => styleExpression
25
+ */
26
+ export declare function createStyleFunction(styleExpression: BabelTypes.Expression, modifierTypes: ModifierType[], t: typeof BabelTypes): BabelTypes.ArrowFunctionExpression;
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Utility functions for processing class modifiers (active:, hover:, focus:, etc.)
3
+ */
4
+
5
+ import type * as BabelTypes from "@babel/types";
6
+ import type { ModifierType, ParsedModifier } from "../../parser/index.js";
7
+ import type { StyleObject } from "../../types/core.js";
8
+ import { getStatePropertyForModifier } from "./componentSupport.js";
9
+
10
+ /**
11
+ * Plugin state interface (subset needed for modifier processing)
12
+ */
13
+ // eslint-disable-next-line @typescript-eslint/consistent-type-definitions
14
+ export interface ModifierProcessingState {
15
+ styleRegistry: Map<string, StyleObject>;
16
+ customColors: Record<string, string>;
17
+ stylesIdentifier: string;
18
+ }
19
+
20
+ /**
21
+ * Process a static className string that contains modifiers
22
+ * Returns a style function expression for Pressable components
23
+ */
24
+ export function processStaticClassNameWithModifiers(
25
+ className: string,
26
+ state: ModifierProcessingState,
27
+ parseClassName: (className: string, customColors: Record<string, string>) => StyleObject,
28
+ generateStyleKey: (className: string) => string,
29
+ splitModifierClasses: (className: string) => { baseClasses: string[]; modifierClasses: ParsedModifier[] },
30
+ t: typeof BabelTypes,
31
+ ) {
32
+ const { baseClasses, modifierClasses } = splitModifierClasses(className);
33
+
34
+ // Parse and register base classes
35
+ let baseStyleExpression: BabelTypes.Node | null = null;
36
+ if (baseClasses.length > 0) {
37
+ const baseClassName = baseClasses.join(" ");
38
+ const baseStyleObject = parseClassName(baseClassName, state.customColors);
39
+ const baseStyleKey = generateStyleKey(baseClassName);
40
+ state.styleRegistry.set(baseStyleKey, baseStyleObject);
41
+ baseStyleExpression = t.memberExpression(t.identifier(state.stylesIdentifier), t.identifier(baseStyleKey));
42
+ }
43
+
44
+ // Parse and register modifier classes
45
+ // Group by modifier type for better organization
46
+ const modifiersByType = new Map<ModifierType, ParsedModifier[]>();
47
+ for (const mod of modifierClasses) {
48
+ if (!modifiersByType.has(mod.modifier)) {
49
+ modifiersByType.set(mod.modifier, []);
50
+ }
51
+ const modGroup = modifiersByType.get(mod.modifier);
52
+ if (modGroup) {
53
+ modGroup.push(mod);
54
+ }
55
+ }
56
+
57
+ // Build style function: ({ pressed }) => [baseStyle, pressed && modifierStyle]
58
+ const styleArrayElements: BabelTypes.Expression[] = [];
59
+
60
+ // Add base style first
61
+ if (baseStyleExpression) {
62
+ styleArrayElements.push(baseStyleExpression);
63
+ }
64
+
65
+ // Add conditional styles for each modifier type
66
+ for (const [modifierType, modifiers] of modifiersByType) {
67
+ // Parse all modifier classes together
68
+ const modifierClassNames = modifiers.map((m) => m.baseClass).join(" ");
69
+ const modifierStyleObject = parseClassName(modifierClassNames, state.customColors);
70
+ const modifierStyleKey = generateStyleKey(`${modifierType}_${modifierClassNames}`);
71
+ state.styleRegistry.set(modifierStyleKey, modifierStyleObject);
72
+
73
+ // Create conditional: pressed && styles._active_bg_blue_700
74
+ const stateProperty = getStatePropertyForModifier(modifierType);
75
+ const conditionalExpression = t.logicalExpression(
76
+ "&&",
77
+ t.identifier(stateProperty),
78
+ t.memberExpression(t.identifier(state.stylesIdentifier), t.identifier(modifierStyleKey)),
79
+ );
80
+
81
+ styleArrayElements.push(conditionalExpression);
82
+ }
83
+
84
+ // If only base style, return it directly; otherwise return array
85
+ if (styleArrayElements.length === 1) {
86
+ return styleArrayElements[0];
87
+ }
88
+
89
+ return t.arrayExpression(styleArrayElements);
90
+ }
91
+
92
+ /**
93
+ * Create a style function for Pressable: ({ pressed }) => styleExpression
94
+ */
95
+ export function createStyleFunction(
96
+ styleExpression: BabelTypes.Expression,
97
+ modifierTypes: ModifierType[],
98
+ t: typeof BabelTypes,
99
+ ) {
100
+ // Build parameter object: { pressed, hovered, focused }
101
+ const paramProperties: BabelTypes.ObjectProperty[] = [];
102
+ const usedStateProps = new Set<string>();
103
+
104
+ for (const modifierType of modifierTypes) {
105
+ const stateProperty = getStatePropertyForModifier(modifierType);
106
+ if (!usedStateProps.has(stateProperty)) {
107
+ usedStateProps.add(stateProperty);
108
+ paramProperties.push(
109
+ t.objectProperty(t.identifier(stateProperty), t.identifier(stateProperty), false, true),
110
+ );
111
+ }
112
+ }
113
+
114
+ const param = t.objectPattern(paramProperties);
115
+
116
+ // Create arrow function: ({ pressed }) => styleExpression
117
+ return t.arrowFunctionExpression([param], styleExpression);
118
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Utility functions for injecting StyleSheet imports and style definitions
3
+ */
4
+ import type { NodePath } from "@babel/core";
5
+ import type * as BabelTypes from "@babel/types";
6
+ import type { StyleObject } from "../../types/core.js";
7
+ /**
8
+ * Add StyleSheet import to the file
9
+ */
10
+ export declare function addStyleSheetImport(path: NodePath<BabelTypes.Program>, t: typeof BabelTypes): void;
11
+ /**
12
+ * Inject StyleSheet.create with all collected styles at the top of the file
13
+ * This ensures the styles object is defined before any code that references it
14
+ */
15
+ export declare function injectStylesAtTop(path: NodePath<BabelTypes.Program>, styleRegistry: Map<string, StyleObject>, stylesIdentifier: string, t: typeof BabelTypes): void;
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Utility functions for injecting StyleSheet imports and style definitions
3
+ */
4
+
5
+ import type { NodePath } from "@babel/core";
6
+ import type * as BabelTypes from "@babel/types";
7
+ import type { StyleObject } from "../../types/core.js";
8
+
9
+ /**
10
+ * Add StyleSheet import to the file
11
+ */
12
+ export function addStyleSheetImport(path: NodePath<BabelTypes.Program>, t: typeof BabelTypes): void {
13
+ const importDeclaration = t.importDeclaration(
14
+ [t.importSpecifier(t.identifier("StyleSheet"), t.identifier("StyleSheet"))],
15
+ t.stringLiteral("react-native"),
16
+ );
17
+
18
+ // Add import at the top of the file
19
+ path.unshiftContainer("body", importDeclaration);
20
+ }
21
+
22
+ /**
23
+ * Inject StyleSheet.create with all collected styles at the top of the file
24
+ * This ensures the styles object is defined before any code that references it
25
+ */
26
+ export function injectStylesAtTop(
27
+ path: NodePath<BabelTypes.Program>,
28
+ styleRegistry: Map<string, StyleObject>,
29
+ stylesIdentifier: string,
30
+ t: typeof BabelTypes,
31
+ ): void {
32
+ // Build style object properties
33
+ const styleProperties: BabelTypes.ObjectProperty[] = [];
34
+
35
+ for (const [key, styleObject] of styleRegistry) {
36
+ const properties = Object.entries(styleObject).map(([styleProp, styleValue]) => {
37
+ let valueNode;
38
+
39
+ if (typeof styleValue === "number") {
40
+ valueNode = t.numericLiteral(styleValue);
41
+ } else if (typeof styleValue === "string") {
42
+ valueNode = t.stringLiteral(styleValue);
43
+ } else {
44
+ // Fallback for other types
45
+ valueNode = t.valueToNode(styleValue);
46
+ }
47
+
48
+ return t.objectProperty(t.identifier(styleProp), valueNode);
49
+ });
50
+
51
+ styleProperties.push(t.objectProperty(t.identifier(key), t.objectExpression(properties)));
52
+ }
53
+
54
+ // Create: const _twStyles = StyleSheet.create({ ... })
55
+ const styleSheet = t.variableDeclaration("const", [
56
+ t.variableDeclarator(
57
+ t.identifier(stylesIdentifier),
58
+ t.callExpression(t.memberExpression(t.identifier("StyleSheet"), t.identifier("create")), [
59
+ t.objectExpression(styleProperties),
60
+ ]),
61
+ ),
62
+ ]);
63
+
64
+ // Find the index to insert after all imports
65
+ const body = path.node.body;
66
+ let insertIndex = 0;
67
+
68
+ // Find the last import statement
69
+ for (let i = 0; i < body.length; i++) {
70
+ if (t.isImportDeclaration(body[i])) {
71
+ insertIndex = i + 1;
72
+ } else {
73
+ // Stop at the first non-import statement
74
+ break;
75
+ }
76
+ }
77
+
78
+ // Insert StyleSheet.create after imports
79
+ body.splice(insertIndex, 0, styleSheet);
80
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Utility functions for transforming and merging style attributes
3
+ */
4
+ import type { NodePath } from "@babel/core";
5
+ import type * as BabelTypes from "@babel/types";
6
+ import type { DynamicExpressionResult } from "./dynamicProcessing.js";
7
+ /**
8
+ * Helper to find existing style attribute on parent JSX element
9
+ */
10
+ export declare function findStyleAttribute(path: NodePath, targetStyleProp: string, t: typeof BabelTypes): BabelTypes.JSXAttribute | undefined;
11
+ /**
12
+ * Replace className with style attribute
13
+ */
14
+ export declare function replaceWithStyleAttribute(classNamePath: NodePath, styleKey: string, targetStyleProp: string, stylesIdentifier: string, t: typeof BabelTypes): void;
15
+ /**
16
+ * Merge className styles with existing style prop
17
+ */
18
+ export declare function mergeStyleAttribute(classNamePath: NodePath, styleAttribute: BabelTypes.JSXAttribute, styleKey: string, stylesIdentifier: string, t: typeof BabelTypes): void;
19
+ /**
20
+ * Replace className with dynamic style attribute
21
+ */
22
+ export declare function replaceDynamicWithStyleAttribute(classNamePath: NodePath, result: DynamicExpressionResult, targetStyleProp: string, t: typeof BabelTypes): void;
23
+ /**
24
+ * Merge dynamic className styles with existing style prop
25
+ */
26
+ export declare function mergeDynamicStyleAttribute(classNamePath: NodePath, styleAttribute: BabelTypes.JSXAttribute, result: DynamicExpressionResult, t: typeof BabelTypes): void;
27
+ /**
28
+ * Replace className with style function attribute (for Pressable with modifiers)
29
+ */
30
+ export declare function replaceWithStyleFunctionAttribute(classNamePath: NodePath, styleFunctionExpression: BabelTypes.Expression, targetStyleProp: string, t: typeof BabelTypes): void;
31
+ /**
32
+ * Merge className style function with existing style prop (for Pressable with modifiers)
33
+ */
34
+ export declare function mergeStyleFunctionAttribute(classNamePath: NodePath, styleAttribute: BabelTypes.JSXAttribute, styleFunctionExpression: BabelTypes.Expression, t: typeof BabelTypes): void;
35
+ /**
36
+ * Add or merge placeholderTextColor prop on a JSX element
37
+ * Handles merging with existing placeholderTextColor if present
38
+ */
39
+ export declare function addOrMergePlaceholderTextColorProp(jsxOpeningElement: BabelTypes.JSXOpeningElement, color: string, t: typeof BabelTypes): void;