@mgcrea/react-native-tailwind 0.2.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 (42) hide show
  1. package/README.md +576 -0
  2. package/dist/babel/config-loader.d.ts +25 -0
  3. package/dist/babel/config-loader.ts +134 -0
  4. package/dist/babel/index.cjs +1111 -0
  5. package/dist/babel/index.d.ts +16 -0
  6. package/dist/babel/index.ts +286 -0
  7. package/dist/index.d.ts +12 -0
  8. package/dist/index.js +1 -0
  9. package/dist/parser/borders.d.ts +10 -0
  10. package/dist/parser/borders.js +1 -0
  11. package/dist/parser/colors.d.ts +9 -0
  12. package/dist/parser/colors.js +1 -0
  13. package/dist/parser/index.d.ts +25 -0
  14. package/dist/parser/index.js +1 -0
  15. package/dist/parser/layout.d.ts +8 -0
  16. package/dist/parser/layout.js +1 -0
  17. package/dist/parser/sizing.d.ts +10 -0
  18. package/dist/parser/sizing.js +1 -0
  19. package/dist/parser/spacing.d.ts +10 -0
  20. package/dist/parser/spacing.js +1 -0
  21. package/dist/parser/typography.d.ts +9 -0
  22. package/dist/parser/typography.js +1 -0
  23. package/dist/react-native.d.js +1 -0
  24. package/dist/react-native.d.ts +138 -0
  25. package/dist/types.d.ts +11 -0
  26. package/dist/types.js +1 -0
  27. package/dist/utils/styleKey.d.ts +9 -0
  28. package/dist/utils/styleKey.js +1 -0
  29. package/package.json +83 -0
  30. package/src/babel/config-loader.ts +134 -0
  31. package/src/babel/index.ts +286 -0
  32. package/src/index.ts +20 -0
  33. package/src/parser/borders.ts +198 -0
  34. package/src/parser/colors.ts +160 -0
  35. package/src/parser/index.ts +71 -0
  36. package/src/parser/layout.ts +114 -0
  37. package/src/parser/sizing.ts +239 -0
  38. package/src/parser/spacing.ts +222 -0
  39. package/src/parser/typography.ts +156 -0
  40. package/src/react-native.d.ts +138 -0
  41. package/src/types.ts +15 -0
  42. package/src/utils/styleKey.ts +23 -0
@@ -0,0 +1,134 @@
1
+ /* eslint-disable @typescript-eslint/no-require-imports */
2
+ /* eslint-disable @typescript-eslint/no-dynamic-delete */
3
+ /**
4
+ * Tailwind config loader for Babel plugin
5
+ * Discovers and loads tailwind.config.* files from the project
6
+ */
7
+
8
+ import * as fs from "fs";
9
+ import * as path from "path";
10
+
11
+ export type TailwindConfig = {
12
+ theme?: {
13
+ extend?: {
14
+ colors?: Record<string, string | Record<string, string>>;
15
+ };
16
+ colors?: Record<string, string | Record<string, string>>;
17
+ };
18
+ };
19
+
20
+ // Cache configs per path to avoid repeated file I/O
21
+ const configCache = new Map<string, TailwindConfig | null>();
22
+
23
+ /**
24
+ * Find tailwind.config.* file by traversing up from startDir
25
+ */
26
+ export function findTailwindConfig(startDir: string): string | null {
27
+ let currentDir = startDir;
28
+ const root = path.parse(currentDir).root;
29
+
30
+ const configNames = [
31
+ "tailwind.config.mjs",
32
+ "tailwind.config.js",
33
+ "tailwind.config.cjs",
34
+ "tailwind.config.ts",
35
+ ];
36
+
37
+ while (currentDir !== root) {
38
+ for (const configName of configNames) {
39
+ const configPath = path.join(currentDir, configName);
40
+ if (fs.existsSync(configPath)) {
41
+ return configPath;
42
+ }
43
+ }
44
+ currentDir = path.dirname(currentDir);
45
+ }
46
+
47
+ return null;
48
+ }
49
+
50
+ /**
51
+ * Load and parse tailwind config file
52
+ */
53
+ export function loadTailwindConfig(configPath: string): TailwindConfig | null {
54
+ // Check cache
55
+ if (configCache.has(configPath)) {
56
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
57
+ return configCache.get(configPath)!;
58
+ }
59
+
60
+ try {
61
+ // Clear require cache to allow hot reloading
62
+ const resolvedPath = require.resolve(configPath);
63
+ delete require.cache[resolvedPath];
64
+
65
+ // Load config
66
+ const config = require(configPath) as TailwindConfig | { default: TailwindConfig };
67
+
68
+ // Handle both default export and direct export
69
+ const resolved: TailwindConfig = "default" in config ? config.default : config;
70
+
71
+ configCache.set(configPath, resolved);
72
+ return resolved;
73
+ } catch (error) {
74
+ if (process.env.NODE_ENV !== "production") {
75
+ console.warn(`[react-native-tailwind] Failed to load config from ${configPath}:`, error);
76
+ }
77
+ configCache.set(configPath, null);
78
+ return null;
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Flatten nested color objects into dot notation
84
+ * Example: { brand: { light: '#fff', dark: '#000' } } -> { 'brand-light': '#fff', 'brand-dark': '#000' }
85
+ */
86
+ function flattenColors(
87
+ colors: Record<string, string | Record<string, string>>,
88
+ prefix = "",
89
+ ): Record<string, string> {
90
+ const result: Record<string, string> = {};
91
+
92
+ for (const [key, value] of Object.entries(colors)) {
93
+ const newKey = prefix ? `${prefix}-${key}` : key;
94
+
95
+ if (typeof value === "string") {
96
+ result[newKey] = value;
97
+ } else if (typeof value === "object" && value !== null) {
98
+ Object.assign(result, flattenColors(value, newKey));
99
+ }
100
+ }
101
+
102
+ return result;
103
+ }
104
+
105
+ /**
106
+ * Extract custom colors from tailwind config
107
+ * Prefers theme.extend.colors over theme.colors to avoid overriding defaults
108
+ */
109
+ export function extractCustomColors(filename: string): Record<string, string> {
110
+ const projectDir = path.dirname(filename);
111
+ const configPath = findTailwindConfig(projectDir);
112
+
113
+ if (!configPath) {
114
+ return {};
115
+ }
116
+
117
+ const config = loadTailwindConfig(configPath);
118
+ if (!config?.theme) {
119
+ return {};
120
+ }
121
+
122
+ // Warn if using theme.colors instead of theme.extend.colors
123
+ if (config.theme.colors && !config.theme.extend?.colors && process.env.NODE_ENV !== "production") {
124
+ console.warn(
125
+ "[react-native-tailwind] Using theme.colors will override all default colors. " +
126
+ "Use theme.extend.colors to add custom colors while keeping defaults.",
127
+ );
128
+ }
129
+
130
+ // Prefer theme.extend.colors
131
+ const colors = config.theme.extend?.colors ?? config.theme.colors ?? {};
132
+
133
+ return flattenColors(colors);
134
+ }