@mgcrea/react-native-tailwind 0.12.1 → 0.13.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 (82) hide show
  1. package/README.md +29 -2014
  2. package/dist/babel/index.cjs +1462 -1155
  3. package/dist/babel/plugin/componentScope.d.ts +26 -0
  4. package/dist/babel/plugin/componentScope.ts +87 -0
  5. package/dist/babel/plugin/state.d.ts +119 -0
  6. package/dist/babel/plugin/state.ts +177 -0
  7. package/dist/babel/plugin/visitors/className.d.ts +11 -0
  8. package/{src/babel/plugin.test.ts → dist/babel/plugin/visitors/className.test.ts} +74 -674
  9. package/dist/babel/plugin/visitors/className.ts +624 -0
  10. package/dist/babel/plugin/visitors/className.windowDimensions.test.ts +406 -0
  11. package/dist/babel/plugin/visitors/imports.d.ts +11 -0
  12. package/dist/babel/plugin/visitors/imports.test.ts +88 -0
  13. package/dist/babel/plugin/visitors/imports.ts +101 -0
  14. package/dist/babel/plugin/visitors/program.d.ts +15 -0
  15. package/dist/babel/plugin/visitors/program.test.ts +325 -0
  16. package/dist/babel/plugin/visitors/program.ts +99 -0
  17. package/dist/babel/plugin/visitors/tw.d.ts +16 -0
  18. package/dist/babel/plugin/visitors/tw.test.ts +620 -0
  19. package/dist/babel/plugin/visitors/tw.ts +148 -0
  20. package/dist/babel/plugin.d.ts +3 -96
  21. package/dist/babel/plugin.test.ts +470 -0
  22. package/dist/babel/plugin.ts +28 -963
  23. package/dist/babel/utils/colorSchemeModifierProcessing.ts +11 -0
  24. package/dist/babel/utils/componentSupport.test.ts +20 -7
  25. package/dist/babel/utils/componentSupport.ts +2 -0
  26. package/dist/babel/utils/modifierProcessing.ts +21 -0
  27. package/dist/babel/utils/platformModifierProcessing.ts +11 -0
  28. package/dist/babel/utils/styleInjection.d.ts +15 -0
  29. package/dist/babel/utils/styleInjection.ts +115 -0
  30. package/dist/babel/utils/twProcessing.ts +11 -0
  31. package/dist/babel/utils/windowDimensionsProcessing.d.ts +56 -0
  32. package/dist/babel/utils/windowDimensionsProcessing.ts +121 -0
  33. package/dist/components/TouchableOpacity.d.ts +35 -0
  34. package/dist/components/TouchableOpacity.js +1 -0
  35. package/dist/components/index.d.ts +3 -0
  36. package/dist/components/index.js +1 -0
  37. package/dist/config/markers.d.ts +5 -0
  38. package/dist/config/markers.js +1 -0
  39. package/dist/index.d.ts +2 -5
  40. package/dist/index.js +1 -1
  41. package/dist/parser/borders.d.ts +3 -1
  42. package/dist/parser/borders.js +1 -1
  43. package/dist/parser/borders.test.js +1 -1
  44. package/dist/parser/colors.js +1 -1
  45. package/dist/parser/colors.test.js +1 -1
  46. package/dist/parser/index.js +1 -1
  47. package/dist/parser/sizing.js +1 -1
  48. package/dist/runtime.cjs +1 -1
  49. package/dist/runtime.cjs.map +4 -4
  50. package/dist/runtime.js +1 -1
  51. package/dist/runtime.js.map +4 -4
  52. package/package.json +1 -1
  53. package/src/babel/plugin/componentScope.ts +87 -0
  54. package/src/babel/plugin/state.ts +177 -0
  55. package/src/babel/plugin/visitors/className.test.ts +1312 -0
  56. package/src/babel/plugin/visitors/className.ts +624 -0
  57. package/src/babel/plugin/visitors/className.windowDimensions.test.ts +406 -0
  58. package/src/babel/plugin/visitors/imports.test.ts +88 -0
  59. package/src/babel/plugin/visitors/imports.ts +101 -0
  60. package/src/babel/plugin/visitors/program.test.ts +325 -0
  61. package/src/babel/plugin/visitors/program.ts +99 -0
  62. package/src/babel/plugin/visitors/tw.test.ts +620 -0
  63. package/src/babel/plugin/visitors/tw.ts +148 -0
  64. package/src/babel/plugin.ts +28 -963
  65. package/src/babel/utils/colorSchemeModifierProcessing.ts +11 -0
  66. package/src/babel/utils/componentSupport.test.ts +20 -7
  67. package/src/babel/utils/componentSupport.ts +2 -0
  68. package/src/babel/utils/modifierProcessing.ts +21 -0
  69. package/src/babel/utils/platformModifierProcessing.ts +11 -0
  70. package/src/babel/utils/styleInjection.ts +115 -0
  71. package/src/babel/utils/twProcessing.ts +11 -0
  72. package/src/babel/utils/windowDimensionsProcessing.ts +121 -0
  73. package/src/components/TouchableOpacity.tsx +71 -0
  74. package/src/components/index.ts +3 -0
  75. package/src/config/markers.ts +5 -0
  76. package/src/index.ts +4 -5
  77. package/src/parser/borders.test.ts +58 -0
  78. package/src/parser/borders.ts +18 -3
  79. package/src/parser/colors.test.ts +249 -0
  80. package/src/parser/colors.ts +38 -0
  81. package/src/parser/index.ts +2 -2
  82. package/src/parser/sizing.ts +11 -0
@@ -5,6 +5,7 @@
5
5
  import type * as BabelTypes from "@babel/types";
6
6
  import type { ColorSchemeModifierType, CustomTheme, ParsedModifier } from "../../parser/index.js";
7
7
  import type { StyleObject } from "../../types/core.js";
8
+ import { hasRuntimeDimensions } from "./windowDimensionsProcessing.js";
8
9
 
9
10
  /**
10
11
  * Plugin state interface (subset needed for color scheme modifier processing)
@@ -66,6 +67,16 @@ export function processColorSchemeModifiers(
66
67
  // Parse all classes for this color scheme together
67
68
  const classNames = modifiers.map((m) => m.baseClass).join(" ");
68
69
  const styleObject = parseClassName(classNames, state.customTheme);
70
+
71
+ // Check for runtime dimensions (w-screen, h-screen)
72
+ if (hasRuntimeDimensions(styleObject)) {
73
+ throw new Error(
74
+ `w-screen and h-screen cannot be combined with color scheme modifiers (dark:, light:, scheme:). ` +
75
+ `Found in: "${scheme}:${classNames}". ` +
76
+ `Use w-screen/h-screen without modifiers instead.`,
77
+ );
78
+ }
79
+
69
80
  const styleKey = generateStyleKey(`${scheme}_${classNames}`);
70
81
 
71
82
  // Register style in the registry
@@ -86,6 +86,26 @@ describe("getComponentModifierSupport", () => {
86
86
  supportedModifiers: ["focus", "disabled", "placeholder"],
87
87
  });
88
88
  });
89
+
90
+ it("should recognize TouchableOpacity component", () => {
91
+ const element = createJSXElement("<TouchableOpacity />");
92
+ const result = getComponentModifierSupport(element, t);
93
+
94
+ expect(result).toEqual({
95
+ component: "TouchableOpacity",
96
+ supportedModifiers: ["active", "disabled"],
97
+ });
98
+ });
99
+
100
+ it("should recognize TouchableOpacity with attributes", () => {
101
+ const element = createJSXElement('<TouchableOpacity className="m-4" onPress={handlePress} />');
102
+ const result = getComponentModifierSupport(element, t);
103
+
104
+ expect(result).toEqual({
105
+ component: "TouchableOpacity",
106
+ supportedModifiers: ["active", "disabled"],
107
+ });
108
+ });
89
109
  });
90
110
 
91
111
  describe("Member expressions", () => {
@@ -139,13 +159,6 @@ describe("getComponentModifierSupport", () => {
139
159
  expect(result).toBeNull();
140
160
  });
141
161
 
142
- it("should return null for TouchableOpacity", () => {
143
- const element = createJSXElement("<TouchableOpacity />");
144
- const result = getComponentModifierSupport(element, t);
145
-
146
- expect(result).toBeNull();
147
- });
148
-
149
162
  it("should return null for custom components", () => {
150
163
  const element = createJSXElement("<CustomButton />");
151
164
  const result = getComponentModifierSupport(element, t);
@@ -41,6 +41,8 @@ export function getComponentModifierSupport(
41
41
  switch (componentName) {
42
42
  case "Pressable":
43
43
  return { component: "Pressable", supportedModifiers: ["active", "hover", "focus", "disabled"] };
44
+ case "TouchableOpacity":
45
+ return { component: "TouchableOpacity", supportedModifiers: ["active", "disabled"] };
44
46
  case "TextInput":
45
47
  return { component: "TextInput", supportedModifiers: ["focus", "disabled", "placeholder"] };
46
48
  default:
@@ -6,6 +6,7 @@ import type * as BabelTypes from "@babel/types";
6
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
+ import { hasRuntimeDimensions } from "./windowDimensionsProcessing.js";
9
10
 
10
11
  /**
11
12
  * Plugin state interface (subset needed for modifier processing)
@@ -36,6 +37,16 @@ export function processStaticClassNameWithModifiers(
36
37
  if (baseClasses.length > 0) {
37
38
  const baseClassName = baseClasses.join(" ");
38
39
  const baseStyleObject = parseClassName(baseClassName, state.customTheme);
40
+
41
+ // Check for runtime dimensions (w-screen, h-screen) in base classes
42
+ if (hasRuntimeDimensions(baseStyleObject)) {
43
+ throw new Error(
44
+ `w-screen and h-screen cannot be combined with state modifiers (active:, hover:, focus:, etc.) or platform modifiers (ios:, android:, web:). ` +
45
+ `Found in: "${baseClassName}". ` +
46
+ `Use w-screen/h-screen without modifiers instead.`,
47
+ );
48
+ }
49
+
39
50
  const baseStyleKey = generateStyleKey(baseClassName);
40
51
  state.styleRegistry.set(baseStyleKey, baseStyleObject);
41
52
  baseStyleExpression = t.memberExpression(t.identifier(state.stylesIdentifier), t.identifier(baseStyleKey));
@@ -67,6 +78,16 @@ export function processStaticClassNameWithModifiers(
67
78
  // Parse all modifier classes together
68
79
  const modifierClassNames = modifiers.map((m) => m.baseClass).join(" ");
69
80
  const modifierStyleObject = parseClassName(modifierClassNames, state.customTheme);
81
+
82
+ // Check for runtime dimensions (w-screen, h-screen) in modifier classes
83
+ if (hasRuntimeDimensions(modifierStyleObject)) {
84
+ throw new Error(
85
+ `w-screen and h-screen cannot be combined with state modifiers (active:, hover:, focus:, etc.) or platform modifiers (ios:, android:, web:). ` +
86
+ `Found in: "${modifierType}:${modifierClassNames}". ` +
87
+ `Use w-screen/h-screen without modifiers instead.`,
88
+ );
89
+ }
90
+
70
91
  const modifierStyleKey = generateStyleKey(`${modifierType}_${modifierClassNames}`);
71
92
  state.styleRegistry.set(modifierStyleKey, modifierStyleObject);
72
93
 
@@ -5,6 +5,7 @@
5
5
  import type * as BabelTypes from "@babel/types";
6
6
  import type { CustomTheme, ParsedModifier, PlatformModifierType } from "../../parser/index.js";
7
7
  import type { StyleObject } from "../../types/core.js";
8
+ import { hasRuntimeDimensions } from "./windowDimensionsProcessing.js";
8
9
 
9
10
  /**
10
11
  * Plugin state interface (subset needed for platform modifier processing)
@@ -62,6 +63,16 @@ export function processPlatformModifiers(
62
63
  // Parse all classes for this platform together
63
64
  const classNames = modifiers.map((m) => m.baseClass).join(" ");
64
65
  const styleObject = parseClassName(classNames, state.customTheme);
66
+
67
+ // Check for runtime dimensions (w-screen, h-screen)
68
+ if (hasRuntimeDimensions(styleObject)) {
69
+ throw new Error(
70
+ `w-screen and h-screen cannot be combined with platform modifiers (ios:, android:, web:). ` +
71
+ `Found in: "${platform}:${classNames}". ` +
72
+ `Use w-screen/h-screen without modifiers instead.`,
73
+ );
74
+ }
75
+
65
76
  const styleKey = generateStyleKey(`${platform}_${classNames}`);
66
77
 
67
78
  // Register style in the registry
@@ -27,6 +27,21 @@ export declare function addColorSchemeImport(path: NodePath<BabelTypes.Program>,
27
27
  * @returns true if hook was injected, false if already exists
28
28
  */
29
29
  export declare function injectColorSchemeHook(functionPath: NodePath<BabelTypes.Function>, colorSchemeVariableName: string, hookName: string, localIdentifier: string | undefined, t: typeof BabelTypes): boolean;
30
+ /**
31
+ * Add useWindowDimensions import to the file or merge with existing react-native import
32
+ */
33
+ export declare function addWindowDimensionsImport(path: NodePath<BabelTypes.Program>, t: typeof BabelTypes): void;
34
+ /**
35
+ * Inject useWindowDimensions hook call at the top of a function component
36
+ *
37
+ * @param functionPath - Path to the function component
38
+ * @param dimensionsVariableName - Name for the dimensions variable
39
+ * @param hookName - Name of the hook to call (e.g., 'useWindowDimensions')
40
+ * @param localIdentifier - Local identifier if hook is already imported with an alias
41
+ * @param t - Babel types
42
+ * @returns true if hook was injected, false if already exists
43
+ */
44
+ export declare function injectWindowDimensionsHook(functionPath: NodePath<BabelTypes.Function>, dimensionsVariableName: string, hookName: string, localIdentifier: string | undefined, t: typeof BabelTypes): boolean;
30
45
  /**
31
46
  * Inject StyleSheet.create with all collected styles at the top of the file
32
47
  * This ensures the styles object is defined before any code that references it
@@ -220,6 +220,121 @@ export function injectColorSchemeHook(
220
220
  return true;
221
221
  }
222
222
 
223
+ /**
224
+ * Add useWindowDimensions import to the file or merge with existing react-native import
225
+ */
226
+ export function addWindowDimensionsImport(path: NodePath<BabelTypes.Program>, t: typeof BabelTypes): void {
227
+ // Check if there's already an import from react-native
228
+ const body = path.node.body;
229
+ let existingValueImport: BabelTypes.ImportDeclaration | null = null;
230
+
231
+ for (const statement of body) {
232
+ if (t.isImportDeclaration(statement) && statement.source.value === "react-native") {
233
+ // Only consider value imports (not type-only imports which get erased)
234
+ if (statement.importKind !== "type") {
235
+ existingValueImport = statement;
236
+ break; // Found a value import, we can stop
237
+ }
238
+ }
239
+ }
240
+
241
+ // If we found a value import (not type-only), merge with it
242
+ if (existingValueImport) {
243
+ // Check if the hook is already imported
244
+ const hasHook = existingValueImport.specifiers.some(
245
+ (spec) =>
246
+ t.isImportSpecifier(spec) &&
247
+ spec.imported.type === "Identifier" &&
248
+ spec.imported.name === "useWindowDimensions",
249
+ );
250
+
251
+ if (!hasHook) {
252
+ // Add hook to existing value import
253
+ existingValueImport.specifiers.push(
254
+ t.importSpecifier(t.identifier("useWindowDimensions"), t.identifier("useWindowDimensions")),
255
+ );
256
+ }
257
+ } else {
258
+ // No value import exists - create a new one
259
+ // (Don't merge with type-only imports as they get erased by Babel/TypeScript)
260
+ const importDeclaration = t.importDeclaration(
261
+ [t.importSpecifier(t.identifier("useWindowDimensions"), t.identifier("useWindowDimensions"))],
262
+ t.stringLiteral("react-native"),
263
+ );
264
+ path.unshiftContainer("body", importDeclaration);
265
+ }
266
+ }
267
+
268
+ /**
269
+ * Inject useWindowDimensions hook call at the top of a function component
270
+ *
271
+ * @param functionPath - Path to the function component
272
+ * @param dimensionsVariableName - Name for the dimensions variable
273
+ * @param hookName - Name of the hook to call (e.g., 'useWindowDimensions')
274
+ * @param localIdentifier - Local identifier if hook is already imported with an alias
275
+ * @param t - Babel types
276
+ * @returns true if hook was injected, false if already exists
277
+ */
278
+ export function injectWindowDimensionsHook(
279
+ functionPath: NodePath<BabelTypes.Function>,
280
+ dimensionsVariableName: string,
281
+ hookName: string,
282
+ localIdentifier: string | undefined,
283
+ t: typeof BabelTypes,
284
+ ): boolean {
285
+ let body = functionPath.node.body;
286
+
287
+ // Handle concise arrow functions: () => <JSX />
288
+ // Convert to block statement: () => { const _twDimensions = useWindowDimensions(); return <JSX />; }
289
+ if (!t.isBlockStatement(body)) {
290
+ if (t.isArrowFunctionExpression(functionPath.node) && t.isExpression(body)) {
291
+ // Convert concise body to block statement with return
292
+ const returnStatement = t.returnStatement(body);
293
+ const blockStatement = t.blockStatement([returnStatement]);
294
+ functionPath.node.body = blockStatement;
295
+ body = blockStatement;
296
+ } else {
297
+ // Other non-block functions (shouldn't happen for components, but be safe)
298
+ return false;
299
+ }
300
+ }
301
+
302
+ // Check if hook is already injected
303
+ const hasHook = body.body.some((statement) => {
304
+ if (
305
+ t.isVariableDeclaration(statement) &&
306
+ statement.declarations.length > 0 &&
307
+ t.isVariableDeclarator(statement.declarations[0])
308
+ ) {
309
+ const declarator = statement.declarations[0];
310
+ return t.isIdentifier(declarator.id) && declarator.id.name === dimensionsVariableName;
311
+ }
312
+ return false;
313
+ });
314
+
315
+ if (hasHook) {
316
+ return false; // Already injected
317
+ }
318
+
319
+ // Use the local identifier if hook was already imported with an alias,
320
+ // otherwise use the configured hook name
321
+ // e.g., import { useWindowDimensions as useDims } → call useDims()
322
+ const identifierToCall = localIdentifier ?? hookName;
323
+
324
+ // Create: const _twDimensions = useWindowDimensions(); (or aliased name if already imported)
325
+ const hookCall = t.variableDeclaration("const", [
326
+ t.variableDeclarator(
327
+ t.identifier(dimensionsVariableName),
328
+ t.callExpression(t.identifier(identifierToCall), []),
329
+ ),
330
+ ]);
331
+
332
+ // Insert at the beginning of function body
333
+ body.body.unshift(hookCall);
334
+
335
+ return true;
336
+ }
337
+
223
338
  /**
224
339
  * Inject StyleSheet.create with all collected styles at the top of the file
225
340
  * This ensures the styles object is defined before any code that references it
@@ -15,6 +15,7 @@ import type { SchemeModifierConfig } from "../../types/config.js";
15
15
  import type { StyleObject } from "../../types/core.js";
16
16
  import { processColorSchemeModifiers } from "./colorSchemeModifierProcessing.js";
17
17
  import { processPlatformModifiers } from "./platformModifierProcessing.js";
18
+ import { hasRuntimeDimensions } from "./windowDimensionsProcessing.js";
18
19
 
19
20
  /**
20
21
  * Plugin state interface (subset needed for tw processing)
@@ -77,6 +78,16 @@ export function processTwCall(
77
78
  if (baseClasses.length > 0) {
78
79
  const baseClassName = baseClasses.join(" ");
79
80
  const baseStyleObject = parseClassName(baseClassName, state.customTheme);
81
+
82
+ // Check for runtime dimensions (w-screen, h-screen)
83
+ if (hasRuntimeDimensions(baseStyleObject)) {
84
+ throw path.buildCodeFrameError(
85
+ `w-screen and h-screen are not supported in tw\`\` or twStyle() calls. ` +
86
+ `Found: "${baseClassName}". ` +
87
+ `Use them in className attributes instead.`,
88
+ );
89
+ }
90
+
80
91
  const baseStyleKey = generateStyleKey(baseClassName);
81
92
  state.styleRegistry.set(baseStyleKey, baseStyleObject);
82
93
 
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Utility functions for processing window dimensions (w-screen, h-screen)
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 window dimensions processing)
8
+ */
9
+ export interface WindowDimensionsProcessingState {
10
+ needsWindowDimensionsImport: boolean;
11
+ windowDimensionsVariableName: string;
12
+ }
13
+ /**
14
+ * Check if a style object contains runtime dimension markers
15
+ *
16
+ * @param styleObject - Style object to check
17
+ * @returns true if the style object contains runtime dimension markers
18
+ *
19
+ * @example
20
+ * hasRuntimeDimensions({ width: "{{RUNTIME:dimensions.width}}" }) // true
21
+ * hasRuntimeDimensions({ width: 100 }) // false
22
+ */
23
+ export declare function hasRuntimeDimensions(styleObject: StyleObject): boolean;
24
+ /**
25
+ * Create an inline style object with runtime dimension access
26
+ *
27
+ * Converts runtime markers like "{{RUNTIME:dimensions.width}}" to
28
+ * AST nodes like: { width: _twDimensions.width }
29
+ *
30
+ * @param styleObject - Style object with runtime markers
31
+ * @param state - Plugin state
32
+ * @param t - Babel types
33
+ * @returns AST object expression for inline style
34
+ *
35
+ * @example
36
+ * Input: { width: "{{RUNTIME:dimensions.width}}", height: "{{RUNTIME:dimensions.height}}" }
37
+ * Output: { width: _twDimensions.width, height: _twDimensions.height }
38
+ */
39
+ export declare function createRuntimeDimensionObject(styleObject: StyleObject, state: WindowDimensionsProcessingState, t: typeof BabelTypes): BabelTypes.ObjectExpression;
40
+ /**
41
+ * Split a style object into static and runtime parts
42
+ *
43
+ * @param styleObject - Style object to split
44
+ * @returns Object with static and runtime style objects
45
+ *
46
+ * @example
47
+ * Input: { width: "{{RUNTIME:dimensions.width}}", padding: 16, backgroundColor: "#fff" }
48
+ * Output: {
49
+ * static: { padding: 16, backgroundColor: "#fff" },
50
+ * runtime: { width: "{{RUNTIME:dimensions.width}}" }
51
+ * }
52
+ */
53
+ export declare function splitStaticAndRuntimeStyles(styleObject: StyleObject): {
54
+ static: StyleObject;
55
+ runtime: StyleObject;
56
+ };
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Utility functions for processing window dimensions (w-screen, h-screen)
3
+ */
4
+
5
+ import type * as BabelTypes from "@babel/types";
6
+ import { RUNTIME_DIMENSIONS_MARKER } from "../../config/markers.js";
7
+ import type { StyleObject } from "../../types/core.js";
8
+
9
+ /**
10
+ * Plugin state interface (subset needed for window dimensions processing)
11
+ */
12
+ // eslint-disable-next-line @typescript-eslint/consistent-type-definitions
13
+ export interface WindowDimensionsProcessingState {
14
+ needsWindowDimensionsImport: boolean;
15
+ windowDimensionsVariableName: string;
16
+ }
17
+
18
+ /**
19
+ * Check if a style object contains runtime dimension markers
20
+ *
21
+ * @param styleObject - Style object to check
22
+ * @returns true if the style object contains runtime dimension markers
23
+ *
24
+ * @example
25
+ * hasRuntimeDimensions({ width: "{{RUNTIME:dimensions.width}}" }) // true
26
+ * hasRuntimeDimensions({ width: 100 }) // false
27
+ */
28
+ export function hasRuntimeDimensions(styleObject: StyleObject): boolean {
29
+ return Object.values(styleObject).some(
30
+ (value) => typeof value === "string" && value.startsWith(RUNTIME_DIMENSIONS_MARKER),
31
+ );
32
+ }
33
+
34
+ /**
35
+ * Create an inline style object with runtime dimension access
36
+ *
37
+ * Converts runtime markers like "{{RUNTIME:dimensions.width}}" to
38
+ * AST nodes like: { width: _twDimensions.width }
39
+ *
40
+ * @param styleObject - Style object with runtime markers
41
+ * @param state - Plugin state
42
+ * @param t - Babel types
43
+ * @returns AST object expression for inline style
44
+ *
45
+ * @example
46
+ * Input: { width: "{{RUNTIME:dimensions.width}}", height: "{{RUNTIME:dimensions.height}}" }
47
+ * Output: { width: _twDimensions.width, height: _twDimensions.height }
48
+ */
49
+ export function createRuntimeDimensionObject(
50
+ styleObject: StyleObject,
51
+ state: WindowDimensionsProcessingState,
52
+ t: typeof BabelTypes,
53
+ ): BabelTypes.ObjectExpression {
54
+ // Mark that we need useWindowDimensions import and hook injection
55
+ state.needsWindowDimensionsImport = true;
56
+
57
+ const properties: BabelTypes.ObjectProperty[] = [];
58
+
59
+ for (const [key, value] of Object.entries(styleObject)) {
60
+ let valueNode: BabelTypes.Expression;
61
+
62
+ if (typeof value === "string" && value.startsWith(RUNTIME_DIMENSIONS_MARKER)) {
63
+ // Extract property name: "{{RUNTIME:dimensions.width}}" -> "width"
64
+ const match = value.match(/dimensions\.(\w+)/);
65
+ const prop = match?.[1];
66
+
67
+ if (prop) {
68
+ // Generate: _twDimensions.width or _twDimensions.height
69
+ valueNode = t.memberExpression(t.identifier(state.windowDimensionsVariableName), t.identifier(prop));
70
+ } else {
71
+ // Fallback: shouldn't happen, but handle gracefully
72
+ valueNode = t.stringLiteral(value);
73
+ }
74
+ } else if (typeof value === "number") {
75
+ valueNode = t.numericLiteral(value);
76
+ } else if (typeof value === "string") {
77
+ valueNode = t.stringLiteral(value);
78
+ } else if (typeof value === "object" && value !== null) {
79
+ // Handle nested objects (e.g., transform arrays)
80
+ valueNode = t.valueToNode(value);
81
+ } else {
82
+ // Handle other types
83
+ valueNode = t.valueToNode(value);
84
+ }
85
+
86
+ properties.push(t.objectProperty(t.identifier(key), valueNode));
87
+ }
88
+
89
+ return t.objectExpression(properties);
90
+ }
91
+
92
+ /**
93
+ * Split a style object into static and runtime parts
94
+ *
95
+ * @param styleObject - Style object to split
96
+ * @returns Object with static and runtime style objects
97
+ *
98
+ * @example
99
+ * Input: { width: "{{RUNTIME:dimensions.width}}", padding: 16, backgroundColor: "#fff" }
100
+ * Output: {
101
+ * static: { padding: 16, backgroundColor: "#fff" },
102
+ * runtime: { width: "{{RUNTIME:dimensions.width}}" }
103
+ * }
104
+ */
105
+ export function splitStaticAndRuntimeStyles(styleObject: StyleObject): {
106
+ static: StyleObject;
107
+ runtime: StyleObject;
108
+ } {
109
+ const staticStyles: StyleObject = {};
110
+ const runtimeStyles: StyleObject = {};
111
+
112
+ for (const [key, value] of Object.entries(styleObject)) {
113
+ if (typeof value === "string" && value.startsWith(RUNTIME_DIMENSIONS_MARKER)) {
114
+ runtimeStyles[key] = value;
115
+ } else {
116
+ staticStyles[key] = value;
117
+ }
118
+ }
119
+
120
+ return { static: staticStyles, runtime: runtimeStyles };
121
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Enhanced TouchableOpacity component with modifier support
3
+ * Adds active state support for active: modifier via onPressIn/onPressOut
4
+ */
5
+ import { type TouchableOpacityProps as RNTouchableOpacityProps, type StyleProp, type ViewStyle } from "react-native";
6
+ type TouchableOpacityState = {
7
+ active: boolean;
8
+ disabled: boolean | null | undefined;
9
+ };
10
+ export type TouchableOpacityProps = Omit<RNTouchableOpacityProps, "style"> & {
11
+ /**
12
+ * Style can be a static style object/array or a function that receives TouchableOpacity state
13
+ */
14
+ style?: StyleProp<ViewStyle> | ((state: TouchableOpacityState) => StyleProp<ViewStyle>);
15
+ className?: string;
16
+ };
17
+ /**
18
+ * Enhanced TouchableOpacity that supports active: and disabled: modifiers
19
+ *
20
+ * @example
21
+ * <TouchableOpacity
22
+ * disabled={isLoading}
23
+ * className="bg-blue-500 active:bg-blue-700 disabled:bg-gray-400"
24
+ * >
25
+ * <Text>Submit</Text>
26
+ * </TouchableOpacity>
27
+ */
28
+ export declare const TouchableOpacity: import("react").ForwardRefExoticComponent<Omit<RNTouchableOpacityProps, "style"> & {
29
+ /**
30
+ * Style can be a static style object/array or a function that receives TouchableOpacity state
31
+ */
32
+ style?: StyleProp<ViewStyle> | ((state: TouchableOpacityState) => StyleProp<ViewStyle>);
33
+ className?: string;
34
+ } & import("react").RefAttributes<import("react-native").View>>;
35
+ export {};
@@ -0,0 +1 @@
1
+ var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:true});exports.TouchableOpacity=void 0;var _slicedToArray2=_interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));var _objectWithoutProperties2=_interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));var _react=require("react");var _reactNative=require("react-native");var _jsxRuntime=require("react/jsx-runtime");var _jsxFileName="/Users/olivier/Projects/github/react-native-tailwind/src/components/TouchableOpacity.tsx";var _excluded=["style","disabled","onPressIn","onPressOut"];var TouchableOpacity=exports.TouchableOpacity=(0,_react.forwardRef)(function TouchableOpacity(_ref,ref){var style=_ref.style,_ref$disabled=_ref.disabled,disabled=_ref$disabled===void 0?false:_ref$disabled,onPressIn=_ref.onPressIn,onPressOut=_ref.onPressOut,props=(0,_objectWithoutProperties2.default)(_ref,_excluded);var _useState=(0,_react.useState)(false),_useState2=(0,_slicedToArray2.default)(_useState,2),isActive=_useState2[0],setIsActive=_useState2[1];var handlePressIn=(0,_react.useCallback)(function(event){setIsActive(true);onPressIn==null||onPressIn(event);},[onPressIn]);var handlePressOut=(0,_react.useCallback)(function(event){setIsActive(false);onPressOut==null||onPressOut(event);},[onPressOut]);var resolvedStyle=typeof style==="function"?style({active:isActive,disabled:disabled}):style;return(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,Object.assign({ref:ref,disabled:disabled,style:resolvedStyle,onPressIn:handlePressIn,onPressOut:handlePressOut},props));});
@@ -0,0 +1,3 @@
1
+ export * from "./Pressable";
2
+ export * from "./TextInput";
3
+ export * from "./TouchableOpacity";
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,"__esModule",{value:true});var _Pressable=require("./Pressable");Object.keys(_Pressable).forEach(function(key){if(key==="default"||key==="__esModule")return;if(key in exports&&exports[key]===_Pressable[key])return;Object.defineProperty(exports,key,{enumerable:true,get:function get(){return _Pressable[key];}});});var _TextInput=require("./TextInput");Object.keys(_TextInput).forEach(function(key){if(key==="default"||key==="__esModule")return;if(key in exports&&exports[key]===_TextInput[key])return;Object.defineProperty(exports,key,{enumerable:true,get:function get(){return _TextInput[key];}});});var _TouchableOpacity=require("./TouchableOpacity");Object.keys(_TouchableOpacity).forEach(function(key){if(key==="default"||key==="__esModule")return;if(key in exports&&exports[key]===_TouchableOpacity[key])return;Object.defineProperty(exports,key,{enumerable:true,get:function get(){return _TouchableOpacity[key];}});});
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Runtime marker prefix for window dimension values
3
+ * Used to mark style values that need runtime evaluation via useWindowDimensions()
4
+ */
5
+ export declare const RUNTIME_DIMENSIONS_MARKER = "{{RUNTIME:dimensions.";
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,"__esModule",{value:true});exports.RUNTIME_DIMENSIONS_MARKER=void 0;var RUNTIME_DIMENSIONS_MARKER=exports.RUNTIME_DIMENSIONS_MARKER="{{RUNTIME:dimensions.";
package/dist/index.d.ts CHANGED
@@ -8,6 +8,7 @@ export { flattenColors } from "./utils/flattenColors";
8
8
  export { generateStyleKey } from "./utils/styleKey";
9
9
  export type { StyleObject } from "./types/core";
10
10
  export type { NativeStyle, TwStyle } from "./types/runtime";
11
+ export { TAILWIND_COLORS } from "./config/tailwind";
11
12
  export { parseAspectRatio, parseBorder, parseColor, parseLayout, parsePlaceholderClass, parsePlaceholderClasses, parseShadow, parseSizing, parseSpacing, parseTypography, } from "./parser";
12
13
  export { ASPECT_RATIO_PRESETS } from "./parser/aspectRatio";
13
14
  export { COLORS } from "./parser/colors";
@@ -16,8 +17,4 @@ export { SHADOW_SCALE } from "./parser/shadows";
16
17
  export { SIZE_PERCENTAGES, SIZE_SCALE } from "./parser/sizing";
17
18
  export { SPACING_SCALE } from "./parser/spacing";
18
19
  export { FONT_SIZES, LETTER_SPACING_SCALE } from "./parser/typography";
19
- export { Pressable } from "./components/Pressable";
20
- export type { PressableProps } from "./components/Pressable";
21
- export { TextInput } from "./components/TextInput";
22
- export type { TextInputProps } from "./components/TextInput";
23
- export { TAILWIND_COLORS } from "./config/tailwind";
20
+ export * from "./components";
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"ASPECT_RATIO_PRESETS",{enumerable:true,get:function get(){return _aspectRatio.ASPECT_RATIO_PRESETS;}});Object.defineProperty(exports,"COLORS",{enumerable:true,get:function get(){return _colors.COLORS;}});Object.defineProperty(exports,"FONT_SIZES",{enumerable:true,get:function get(){return _typography.FONT_SIZES;}});Object.defineProperty(exports,"INSET_SCALE",{enumerable:true,get:function get(){return _layout.INSET_SCALE;}});Object.defineProperty(exports,"LETTER_SPACING_SCALE",{enumerable:true,get:function get(){return _typography.LETTER_SPACING_SCALE;}});Object.defineProperty(exports,"Pressable",{enumerable:true,get:function get(){return _Pressable.Pressable;}});Object.defineProperty(exports,"SHADOW_SCALE",{enumerable:true,get:function get(){return _shadows.SHADOW_SCALE;}});Object.defineProperty(exports,"SIZE_PERCENTAGES",{enumerable:true,get:function get(){return _sizing.SIZE_PERCENTAGES;}});Object.defineProperty(exports,"SIZE_SCALE",{enumerable:true,get:function get(){return _sizing.SIZE_SCALE;}});Object.defineProperty(exports,"SPACING_SCALE",{enumerable:true,get:function get(){return _spacing.SPACING_SCALE;}});Object.defineProperty(exports,"TAILWIND_COLORS",{enumerable:true,get:function get(){return _tailwind.TAILWIND_COLORS;}});Object.defineProperty(exports,"TextInput",{enumerable:true,get:function get(){return _TextInput.TextInput;}});Object.defineProperty(exports,"Z_INDEX_SCALE",{enumerable:true,get:function get(){return _layout.Z_INDEX_SCALE;}});Object.defineProperty(exports,"flattenColors",{enumerable:true,get:function get(){return _flattenColors.flattenColors;}});Object.defineProperty(exports,"generateStyleKey",{enumerable:true,get:function get(){return _styleKey.generateStyleKey;}});Object.defineProperty(exports,"parseAspectRatio",{enumerable:true,get:function get(){return _parser.parseAspectRatio;}});Object.defineProperty(exports,"parseBorder",{enumerable:true,get:function get(){return _parser.parseBorder;}});Object.defineProperty(exports,"parseClass",{enumerable:true,get:function get(){return _parser.parseClass;}});Object.defineProperty(exports,"parseClassName",{enumerable:true,get:function get(){return _parser.parseClassName;}});Object.defineProperty(exports,"parseColor",{enumerable:true,get:function get(){return _parser.parseColor;}});Object.defineProperty(exports,"parseLayout",{enumerable:true,get:function get(){return _parser.parseLayout;}});Object.defineProperty(exports,"parsePlaceholderClass",{enumerable:true,get:function get(){return _parser.parsePlaceholderClass;}});Object.defineProperty(exports,"parsePlaceholderClasses",{enumerable:true,get:function get(){return _parser.parsePlaceholderClasses;}});Object.defineProperty(exports,"parseShadow",{enumerable:true,get:function get(){return _parser.parseShadow;}});Object.defineProperty(exports,"parseSizing",{enumerable:true,get:function get(){return _parser.parseSizing;}});Object.defineProperty(exports,"parseSpacing",{enumerable:true,get:function get(){return _parser.parseSpacing;}});Object.defineProperty(exports,"parseTypography",{enumerable:true,get:function get(){return _parser.parseTypography;}});Object.defineProperty(exports,"tw",{enumerable:true,get:function get(){return _tw.tw;}});Object.defineProperty(exports,"twStyle",{enumerable:true,get:function get(){return _tw.twStyle;}});var _tw=require("./stubs/tw");var _parser=require("./parser");var _flattenColors=require("./utils/flattenColors");var _styleKey=require("./utils/styleKey");var _aspectRatio=require("./parser/aspectRatio");var _colors=require("./parser/colors");var _layout=require("./parser/layout");var _shadows=require("./parser/shadows");var _sizing=require("./parser/sizing");var _spacing=require("./parser/spacing");var _typography=require("./parser/typography");var _Pressable=require("./components/Pressable");var _TextInput=require("./components/TextInput");var _tailwind=require("./config/tailwind");
1
+ Object.defineProperty(exports,"__esModule",{value:true});var _exportNames={tw:true,twStyle:true,parseClass:true,parseClassName:true,parseAspectRatio:true,parseBorder:true,parseColor:true,parseLayout:true,parsePlaceholderClass:true,parsePlaceholderClasses:true,parseShadow:true,parseSizing:true,parseSpacing:true,parseTypography:true,flattenColors:true,generateStyleKey:true,TAILWIND_COLORS:true,ASPECT_RATIO_PRESETS:true,COLORS:true,INSET_SCALE:true,Z_INDEX_SCALE:true,SHADOW_SCALE:true,SIZE_PERCENTAGES:true,SIZE_SCALE:true,SPACING_SCALE:true,FONT_SIZES:true,LETTER_SPACING_SCALE:true};Object.defineProperty(exports,"ASPECT_RATIO_PRESETS",{enumerable:true,get:function get(){return _aspectRatio.ASPECT_RATIO_PRESETS;}});Object.defineProperty(exports,"COLORS",{enumerable:true,get:function get(){return _colors.COLORS;}});Object.defineProperty(exports,"FONT_SIZES",{enumerable:true,get:function get(){return _typography.FONT_SIZES;}});Object.defineProperty(exports,"INSET_SCALE",{enumerable:true,get:function get(){return _layout.INSET_SCALE;}});Object.defineProperty(exports,"LETTER_SPACING_SCALE",{enumerable:true,get:function get(){return _typography.LETTER_SPACING_SCALE;}});Object.defineProperty(exports,"SHADOW_SCALE",{enumerable:true,get:function get(){return _shadows.SHADOW_SCALE;}});Object.defineProperty(exports,"SIZE_PERCENTAGES",{enumerable:true,get:function get(){return _sizing.SIZE_PERCENTAGES;}});Object.defineProperty(exports,"SIZE_SCALE",{enumerable:true,get:function get(){return _sizing.SIZE_SCALE;}});Object.defineProperty(exports,"SPACING_SCALE",{enumerable:true,get:function get(){return _spacing.SPACING_SCALE;}});Object.defineProperty(exports,"TAILWIND_COLORS",{enumerable:true,get:function get(){return _tailwind.TAILWIND_COLORS;}});Object.defineProperty(exports,"Z_INDEX_SCALE",{enumerable:true,get:function get(){return _layout.Z_INDEX_SCALE;}});Object.defineProperty(exports,"flattenColors",{enumerable:true,get:function get(){return _flattenColors.flattenColors;}});Object.defineProperty(exports,"generateStyleKey",{enumerable:true,get:function get(){return _styleKey.generateStyleKey;}});Object.defineProperty(exports,"parseAspectRatio",{enumerable:true,get:function get(){return _parser.parseAspectRatio;}});Object.defineProperty(exports,"parseBorder",{enumerable:true,get:function get(){return _parser.parseBorder;}});Object.defineProperty(exports,"parseClass",{enumerable:true,get:function get(){return _parser.parseClass;}});Object.defineProperty(exports,"parseClassName",{enumerable:true,get:function get(){return _parser.parseClassName;}});Object.defineProperty(exports,"parseColor",{enumerable:true,get:function get(){return _parser.parseColor;}});Object.defineProperty(exports,"parseLayout",{enumerable:true,get:function get(){return _parser.parseLayout;}});Object.defineProperty(exports,"parsePlaceholderClass",{enumerable:true,get:function get(){return _parser.parsePlaceholderClass;}});Object.defineProperty(exports,"parsePlaceholderClasses",{enumerable:true,get:function get(){return _parser.parsePlaceholderClasses;}});Object.defineProperty(exports,"parseShadow",{enumerable:true,get:function get(){return _parser.parseShadow;}});Object.defineProperty(exports,"parseSizing",{enumerable:true,get:function get(){return _parser.parseSizing;}});Object.defineProperty(exports,"parseSpacing",{enumerable:true,get:function get(){return _parser.parseSpacing;}});Object.defineProperty(exports,"parseTypography",{enumerable:true,get:function get(){return _parser.parseTypography;}});Object.defineProperty(exports,"tw",{enumerable:true,get:function get(){return _tw.tw;}});Object.defineProperty(exports,"twStyle",{enumerable:true,get:function get(){return _tw.twStyle;}});var _tw=require("./stubs/tw");var _parser=require("./parser");var _flattenColors=require("./utils/flattenColors");var _styleKey=require("./utils/styleKey");var _tailwind=require("./config/tailwind");var _aspectRatio=require("./parser/aspectRatio");var _colors=require("./parser/colors");var _layout=require("./parser/layout");var _shadows=require("./parser/shadows");var _sizing=require("./parser/sizing");var _spacing=require("./parser/spacing");var _typography=require("./parser/typography");var _components=require("./components");Object.keys(_components).forEach(function(key){if(key==="default"||key==="__esModule")return;if(Object.prototype.hasOwnProperty.call(_exportNames,key))return;if(key in exports&&exports[key]===_components[key])return;Object.defineProperty(exports,key,{enumerable:true,get:function get(){return _components[key];}});});
@@ -6,5 +6,7 @@ export declare const BORDER_WIDTH_SCALE: Record<string, number>;
6
6
  export declare const BORDER_RADIUS_SCALE: Record<string, number>;
7
7
  /**
8
8
  * Parse border classes
9
+ * @param cls - The class name to parse
10
+ * @param customColors - Optional custom colors from tailwind.config (used to detect color patterns)
9
11
  */
10
- export declare function parseBorder(cls: string): StyleObject | null;
12
+ export declare function parseBorder(cls: string, customColors?: Record<string, string>): StyleObject | null;
@@ -1 +1 @@
1
- var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:true});exports.BORDER_WIDTH_SCALE=exports.BORDER_RADIUS_SCALE=void 0;exports.parseBorder=parseBorder;var _defineProperty2=_interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));var BORDER_WIDTH_SCALE=exports.BORDER_WIDTH_SCALE={"":1,"0":0,"2":2,"4":4,"8":8};var BORDER_RADIUS_SCALE=exports.BORDER_RADIUS_SCALE={none:0,sm:2,"":4,md:6,lg:8,xl:12,"2xl":16,"3xl":24,full:9999};var BORDER_WIDTH_PROP_MAP={t:"borderTopWidth",r:"borderRightWidth",b:"borderBottomWidth",l:"borderLeftWidth"};var BORDER_RADIUS_CORNER_MAP={tl:"borderTopLeftRadius",tr:"borderTopRightRadius",bl:"borderBottomLeftRadius",br:"borderBottomRightRadius"};var BORDER_RADIUS_SIDE_MAP={t:["borderTopLeftRadius","borderTopRightRadius"],r:["borderTopRightRadius","borderBottomRightRadius"],b:["borderBottomLeftRadius","borderBottomRightRadius"],l:["borderTopLeftRadius","borderBottomLeftRadius"]};function parseArbitraryBorderWidth(value){var pxMatch=value.match(/^\[(\d+)(?:px)?\]$/);if(pxMatch){return parseInt(pxMatch[1],10);}if(value.startsWith("[")&&value.endsWith("]")){if(process.env.NODE_ENV!=="production"){console.warn(`[react-native-tailwind] Unsupported arbitrary border width value: ${value}. Only px values are supported (e.g., [8px] or [8]).`);}return null;}return null;}function parseArbitraryBorderRadius(value){var pxMatch=value.match(/^\[(\d+)(?:px)?\]$/);if(pxMatch){return parseInt(pxMatch[1],10);}if(value.startsWith("[")&&value.endsWith("]")){if(process.env.NODE_ENV!=="production"){console.warn(`[react-native-tailwind] Unsupported arbitrary border radius value: ${value}. Only px values are supported (e.g., [12px] or [12]).`);}return null;}return null;}function parseBorder(cls){if(cls==="border-solid")return{borderStyle:"solid"};if(cls==="border-dotted")return{borderStyle:"dotted"};if(cls==="border-dashed")return{borderStyle:"dashed"};if(cls.startsWith("border-")){return parseBorderWidth(cls);}if(cls==="border"){return{borderWidth:1};}if(cls.startsWith("rounded")){return parseBorderRadius(cls);}return null;}function parseBorderWidth(cls){var dirMatch=cls.match(/^border-([trbl])(?:-(.+))?$/);if(dirMatch){var dir=dirMatch[1];var valueStr=dirMatch[2]||"";if(valueStr.startsWith("[")){var arbitraryValue=parseArbitraryBorderWidth(valueStr);if(arbitraryValue!==null){return(0,_defineProperty2.default)({},BORDER_WIDTH_PROP_MAP[dir],arbitraryValue);}return null;}var scaleValue=BORDER_WIDTH_SCALE[valueStr];if(scaleValue!==undefined){return(0,_defineProperty2.default)({},BORDER_WIDTH_PROP_MAP[dir],scaleValue);}return null;}var allMatch=cls.match(/^border-(\d+)$/);if(allMatch){var value=BORDER_WIDTH_SCALE[allMatch[1]];if(value!==undefined){return{borderWidth:value};}}var allArbMatch=cls.match(/^border-(\[.+\])$/);if(allArbMatch){var _arbitraryValue=parseArbitraryBorderWidth(allArbMatch[1]);if(_arbitraryValue!==null){return{borderWidth:_arbitraryValue};}}return null;}function parseBorderRadius(cls){var withoutPrefix=cls.substring(7);if(withoutPrefix===""){return{borderRadius:BORDER_RADIUS_SCALE[""]};}if(!withoutPrefix.startsWith("-")){return null;}var rest=withoutPrefix.substring(1);if(rest===""){return null;}var cornerMatch=rest.match(/^(tl|tr|bl|br)(?:-(.+))?$/);if(cornerMatch){var corner=cornerMatch[1];var valueStr=cornerMatch[2]||"";if(valueStr.startsWith("[")){var arbitraryValue=parseArbitraryBorderRadius(valueStr);if(arbitraryValue!==null){return(0,_defineProperty2.default)({},BORDER_RADIUS_CORNER_MAP[corner],arbitraryValue);}return null;}var _scaleValue=BORDER_RADIUS_SCALE[valueStr];if(_scaleValue!==undefined){return(0,_defineProperty2.default)({},BORDER_RADIUS_CORNER_MAP[corner],_scaleValue);}return null;}var sideMatch=rest.match(/^([trbl])(?:-(.+))?$/);if(sideMatch){var side=sideMatch[1];var _valueStr=sideMatch[2]||"";var value;if(_valueStr.startsWith("[")){var _arbitraryValue2=parseArbitraryBorderRadius(_valueStr);if(_arbitraryValue2!==null){value=_arbitraryValue2;}else{return null;}}else{value=BORDER_RADIUS_SCALE[_valueStr];}if(value!==undefined){var result={};BORDER_RADIUS_SIDE_MAP[side].forEach(function(prop){return result[prop]=value;});return result;}return null;}if(rest.startsWith("[")){var _arbitraryValue3=parseArbitraryBorderRadius(rest);if(_arbitraryValue3!==null){return{borderRadius:_arbitraryValue3};}return null;}var scaleValue=BORDER_RADIUS_SCALE[rest];if(scaleValue!==undefined){return{borderRadius:scaleValue};}return null;}
1
+ var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:true});exports.BORDER_WIDTH_SCALE=exports.BORDER_RADIUS_SCALE=void 0;exports.parseBorder=parseBorder;var _defineProperty2=_interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));var _colors=require("./colors");var BORDER_WIDTH_SCALE=exports.BORDER_WIDTH_SCALE={"":1,"0":0,"2":2,"4":4,"8":8};var BORDER_RADIUS_SCALE=exports.BORDER_RADIUS_SCALE={none:0,sm:2,"":4,md:6,lg:8,xl:12,"2xl":16,"3xl":24,full:9999};var BORDER_WIDTH_PROP_MAP={t:"borderTopWidth",r:"borderRightWidth",b:"borderBottomWidth",l:"borderLeftWidth"};var BORDER_RADIUS_CORNER_MAP={tl:"borderTopLeftRadius",tr:"borderTopRightRadius",bl:"borderBottomLeftRadius",br:"borderBottomRightRadius"};var BORDER_RADIUS_SIDE_MAP={t:["borderTopLeftRadius","borderTopRightRadius"],r:["borderTopRightRadius","borderBottomRightRadius"],b:["borderBottomLeftRadius","borderBottomRightRadius"],l:["borderTopLeftRadius","borderBottomLeftRadius"]};function parseArbitraryBorderWidth(value){var pxMatch=value.match(/^\[(\d+)(?:px)?\]$/);if(pxMatch){return parseInt(pxMatch[1],10);}if(value.startsWith("[")&&value.endsWith("]")){if(process.env.NODE_ENV!=="production"){console.warn(`[react-native-tailwind] Unsupported arbitrary border width value: ${value}. Only px values are supported (e.g., [8px] or [8]).`);}return null;}return null;}function parseArbitraryBorderRadius(value){var pxMatch=value.match(/^\[(\d+)(?:px)?\]$/);if(pxMatch){return parseInt(pxMatch[1],10);}if(value.startsWith("[")&&value.endsWith("]")){if(process.env.NODE_ENV!=="production"){console.warn(`[react-native-tailwind] Unsupported arbitrary border radius value: ${value}. Only px values are supported (e.g., [12px] or [12]).`);}return null;}return null;}function parseBorder(cls,customColors){if(cls==="border-solid")return{borderStyle:"solid"};if(cls==="border-dotted")return{borderStyle:"dotted"};if(cls==="border-dashed")return{borderStyle:"dashed"};if(cls.startsWith("border-")){return parseBorderWidth(cls,customColors);}if(cls==="border"){return{borderWidth:1};}if(cls.startsWith("rounded")){return parseBorderRadius(cls);}return null;}function parseBorderWidth(cls,customColors){var dirMatch=cls.match(/^border-([trbl])(?:-(.+))?$/);if(dirMatch){var dir=dirMatch[1];var valueStr=dirMatch[2]||"";if(valueStr){var colorResult=(0,_colors.parseColor)(cls,customColors);if(colorResult!==null){return null;}}if(valueStr.startsWith("[")){var arbitraryValue=parseArbitraryBorderWidth(valueStr);if(arbitraryValue!==null){return(0,_defineProperty2.default)({},BORDER_WIDTH_PROP_MAP[dir],arbitraryValue);}return null;}var scaleValue=BORDER_WIDTH_SCALE[valueStr];if(scaleValue!==undefined){return(0,_defineProperty2.default)({},BORDER_WIDTH_PROP_MAP[dir],scaleValue);}return null;}var allMatch=cls.match(/^border-(\d+)$/);if(allMatch){var value=BORDER_WIDTH_SCALE[allMatch[1]];if(value!==undefined){return{borderWidth:value};}}var allArbMatch=cls.match(/^border-(\[.+\])$/);if(allArbMatch){var _arbitraryValue=parseArbitraryBorderWidth(allArbMatch[1]);if(_arbitraryValue!==null){return{borderWidth:_arbitraryValue};}}return null;}function parseBorderRadius(cls){var withoutPrefix=cls.substring(7);if(withoutPrefix===""){return{borderRadius:BORDER_RADIUS_SCALE[""]};}if(!withoutPrefix.startsWith("-")){return null;}var rest=withoutPrefix.substring(1);if(rest===""){return null;}var cornerMatch=rest.match(/^(tl|tr|bl|br)(?:-(.+))?$/);if(cornerMatch){var corner=cornerMatch[1];var valueStr=cornerMatch[2]||"";if(valueStr.startsWith("[")){var arbitraryValue=parseArbitraryBorderRadius(valueStr);if(arbitraryValue!==null){return(0,_defineProperty2.default)({},BORDER_RADIUS_CORNER_MAP[corner],arbitraryValue);}return null;}var _scaleValue=BORDER_RADIUS_SCALE[valueStr];if(_scaleValue!==undefined){return(0,_defineProperty2.default)({},BORDER_RADIUS_CORNER_MAP[corner],_scaleValue);}return null;}var sideMatch=rest.match(/^([trbl])(?:-(.+))?$/);if(sideMatch){var side=sideMatch[1];var _valueStr=sideMatch[2]||"";var value;if(_valueStr.startsWith("[")){var _arbitraryValue2=parseArbitraryBorderRadius(_valueStr);if(_arbitraryValue2!==null){value=_arbitraryValue2;}else{return null;}}else{value=BORDER_RADIUS_SCALE[_valueStr];}if(value!==undefined){var result={};BORDER_RADIUS_SIDE_MAP[side].forEach(function(prop){return result[prop]=value;});return result;}return null;}if(rest.startsWith("[")){var _arbitraryValue3=parseArbitraryBorderRadius(rest);if(_arbitraryValue3!==null){return{borderRadius:_arbitraryValue3};}return null;}var scaleValue=BORDER_RADIUS_SCALE[rest];if(scaleValue!==undefined){return{borderRadius:scaleValue};}return null;}