@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.
- package/README.md +576 -0
- package/dist/babel/config-loader.d.ts +25 -0
- package/dist/babel/config-loader.ts +134 -0
- package/dist/babel/index.cjs +1111 -0
- package/dist/babel/index.d.ts +16 -0
- package/dist/babel/index.ts +286 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +1 -0
- package/dist/parser/borders.d.ts +10 -0
- package/dist/parser/borders.js +1 -0
- package/dist/parser/colors.d.ts +9 -0
- package/dist/parser/colors.js +1 -0
- package/dist/parser/index.d.ts +25 -0
- package/dist/parser/index.js +1 -0
- package/dist/parser/layout.d.ts +8 -0
- package/dist/parser/layout.js +1 -0
- package/dist/parser/sizing.d.ts +10 -0
- package/dist/parser/sizing.js +1 -0
- package/dist/parser/spacing.d.ts +10 -0
- package/dist/parser/spacing.js +1 -0
- package/dist/parser/typography.d.ts +9 -0
- package/dist/parser/typography.js +1 -0
- package/dist/react-native.d.js +1 -0
- package/dist/react-native.d.ts +138 -0
- package/dist/types.d.ts +11 -0
- package/dist/types.js +1 -0
- package/dist/utils/styleKey.d.ts +9 -0
- package/dist/utils/styleKey.js +1 -0
- package/package.json +83 -0
- package/src/babel/config-loader.ts +134 -0
- package/src/babel/index.ts +286 -0
- package/src/index.ts +20 -0
- package/src/parser/borders.ts +198 -0
- package/src/parser/colors.ts +160 -0
- package/src/parser/index.ts +71 -0
- package/src/parser/layout.ts +114 -0
- package/src/parser/sizing.ts +239 -0
- package/src/parser/spacing.ts +222 -0
- package/src/parser/typography.ts +156 -0
- package/src/react-native.d.ts +138 -0
- package/src/types.ts +15 -0
- 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
|
+
}
|