@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,1111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/babel/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
default: () => reactNativeTailwindBabelPlugin
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(index_exports);
|
|
36
|
+
|
|
37
|
+
// src/parser/borders.ts
|
|
38
|
+
var BORDER_WIDTH_SCALE = {
|
|
39
|
+
"": 1,
|
|
40
|
+
"0": 0,
|
|
41
|
+
"2": 2,
|
|
42
|
+
"4": 4,
|
|
43
|
+
"8": 8
|
|
44
|
+
};
|
|
45
|
+
var BORDER_RADIUS_SCALE = {
|
|
46
|
+
none: 0,
|
|
47
|
+
sm: 2,
|
|
48
|
+
"": 4,
|
|
49
|
+
md: 6,
|
|
50
|
+
lg: 8,
|
|
51
|
+
xl: 12,
|
|
52
|
+
"2xl": 16,
|
|
53
|
+
"3xl": 24,
|
|
54
|
+
full: 9999
|
|
55
|
+
};
|
|
56
|
+
function parseBorder(cls) {
|
|
57
|
+
if (cls.startsWith("border-")) {
|
|
58
|
+
return parseBorderWidth(cls);
|
|
59
|
+
}
|
|
60
|
+
if (cls === "border") {
|
|
61
|
+
return { borderWidth: 1 };
|
|
62
|
+
}
|
|
63
|
+
if (cls.startsWith("rounded")) {
|
|
64
|
+
return parseBorderRadius(cls);
|
|
65
|
+
}
|
|
66
|
+
if (cls === "border-solid") return { borderStyle: "solid" };
|
|
67
|
+
if (cls === "border-dotted") return { borderStyle: "dotted" };
|
|
68
|
+
if (cls === "border-dashed") return { borderStyle: "dashed" };
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
function parseBorderWidth(cls) {
|
|
72
|
+
const allArbMatch = cls.match(/^border-\[(\d+)(?:px)?\]$/);
|
|
73
|
+
if (allArbMatch) {
|
|
74
|
+
return { borderWidth: parseInt(allArbMatch[1], 10) };
|
|
75
|
+
}
|
|
76
|
+
const dirArbMatch = cls.match(/^border-([trbl])-\[(\d+)(?:px)?\]$/);
|
|
77
|
+
if (dirArbMatch) {
|
|
78
|
+
const dir = dirArbMatch[1];
|
|
79
|
+
const value = parseInt(dirArbMatch[2], 10);
|
|
80
|
+
const propMap = {
|
|
81
|
+
t: "borderTopWidth",
|
|
82
|
+
r: "borderRightWidth",
|
|
83
|
+
b: "borderBottomWidth",
|
|
84
|
+
l: "borderLeftWidth"
|
|
85
|
+
};
|
|
86
|
+
return { [propMap[dir]]: value };
|
|
87
|
+
}
|
|
88
|
+
const dirMatch = cls.match(/^border-([trbl])-?(\d*)$/);
|
|
89
|
+
if (dirMatch) {
|
|
90
|
+
const dir = dirMatch[1];
|
|
91
|
+
const scaleKey = dirMatch[2] || "";
|
|
92
|
+
const value = BORDER_WIDTH_SCALE[scaleKey];
|
|
93
|
+
if (typeof value === "number") {
|
|
94
|
+
const propMap = {
|
|
95
|
+
t: "borderTopWidth",
|
|
96
|
+
r: "borderRightWidth",
|
|
97
|
+
b: "borderBottomWidth",
|
|
98
|
+
l: "borderLeftWidth"
|
|
99
|
+
};
|
|
100
|
+
return { [propMap[dir]]: value };
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const allMatch = cls.match(/^border-(\d+)$/);
|
|
104
|
+
if (allMatch) {
|
|
105
|
+
const value = BORDER_WIDTH_SCALE[allMatch[1]];
|
|
106
|
+
if (value !== void 0) {
|
|
107
|
+
return { borderWidth: value };
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
function parseBorderRadius(cls) {
|
|
113
|
+
const allArbMatch = cls.match(/^rounded-\[(\d+)(?:px)?\]$/);
|
|
114
|
+
if (allArbMatch) {
|
|
115
|
+
return { borderRadius: parseInt(allArbMatch[1], 10) };
|
|
116
|
+
}
|
|
117
|
+
const cornerArbMatch = cls.match(/^rounded-(tl|tr|bl|br)-\[(\d+)(?:px)?\]$/);
|
|
118
|
+
if (cornerArbMatch) {
|
|
119
|
+
const corner = cornerArbMatch[1];
|
|
120
|
+
const value = parseInt(cornerArbMatch[2], 10);
|
|
121
|
+
const propMap = {
|
|
122
|
+
tl: "borderTopLeftRadius",
|
|
123
|
+
tr: "borderTopRightRadius",
|
|
124
|
+
bl: "borderBottomLeftRadius",
|
|
125
|
+
br: "borderBottomRightRadius"
|
|
126
|
+
};
|
|
127
|
+
return { [propMap[corner]]: value };
|
|
128
|
+
}
|
|
129
|
+
const sideArbMatch = cls.match(/^rounded-([trbl])-\[(\d+)(?:px)?\]$/);
|
|
130
|
+
if (sideArbMatch) {
|
|
131
|
+
const side = sideArbMatch[1];
|
|
132
|
+
const value = parseInt(sideArbMatch[2], 10);
|
|
133
|
+
const propMap = {
|
|
134
|
+
t: ["borderTopLeftRadius", "borderTopRightRadius"],
|
|
135
|
+
r: ["borderTopRightRadius", "borderBottomRightRadius"],
|
|
136
|
+
b: ["borderBottomLeftRadius", "borderBottomRightRadius"],
|
|
137
|
+
l: ["borderTopLeftRadius", "borderBottomLeftRadius"]
|
|
138
|
+
};
|
|
139
|
+
const result = {};
|
|
140
|
+
propMap[side].forEach((prop) => result[prop] = value);
|
|
141
|
+
return result;
|
|
142
|
+
}
|
|
143
|
+
const allMatch = cls.match(/^rounded(-\w+)?$/);
|
|
144
|
+
if (allMatch) {
|
|
145
|
+
const scaleKey = allMatch[1] ? allMatch[1].substring(1) : "";
|
|
146
|
+
const value = BORDER_RADIUS_SCALE[scaleKey];
|
|
147
|
+
if (value !== void 0) {
|
|
148
|
+
return { borderRadius: value };
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
const sideMatch = cls.match(/^rounded-([trbl])(?:-(\w+))?$/);
|
|
152
|
+
if (sideMatch) {
|
|
153
|
+
const side = sideMatch[1];
|
|
154
|
+
const scaleKey = sideMatch[2] || "";
|
|
155
|
+
const value = BORDER_RADIUS_SCALE[scaleKey];
|
|
156
|
+
if (value !== void 0) {
|
|
157
|
+
const propMap = {
|
|
158
|
+
t: ["borderTopLeftRadius", "borderTopRightRadius"],
|
|
159
|
+
r: ["borderTopRightRadius", "borderBottomRightRadius"],
|
|
160
|
+
b: ["borderBottomLeftRadius", "borderBottomRightRadius"],
|
|
161
|
+
l: ["borderTopLeftRadius", "borderBottomLeftRadius"]
|
|
162
|
+
};
|
|
163
|
+
const result = {};
|
|
164
|
+
propMap[side].forEach((prop) => result[prop] = value);
|
|
165
|
+
return result;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
const cornerMatch = cls.match(/^rounded-(tl|tr|bl|br)(?:-(\w+))?$/);
|
|
169
|
+
if (cornerMatch) {
|
|
170
|
+
const corner = cornerMatch[1];
|
|
171
|
+
const scaleKey = cornerMatch[2] || "";
|
|
172
|
+
const value = BORDER_RADIUS_SCALE[scaleKey];
|
|
173
|
+
if (value !== void 0) {
|
|
174
|
+
const propMap = {
|
|
175
|
+
tl: "borderTopLeftRadius",
|
|
176
|
+
tr: "borderTopRightRadius",
|
|
177
|
+
bl: "borderBottomLeftRadius",
|
|
178
|
+
br: "borderBottomRightRadius"
|
|
179
|
+
};
|
|
180
|
+
return { [propMap[corner]]: value };
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// src/parser/colors.ts
|
|
187
|
+
var COLORS = {
|
|
188
|
+
// Gray
|
|
189
|
+
"gray-50": "#F9FAFB",
|
|
190
|
+
"gray-100": "#F3F4F6",
|
|
191
|
+
"gray-200": "#E5E7EB",
|
|
192
|
+
"gray-300": "#D1D5DB",
|
|
193
|
+
"gray-400": "#9CA3AF",
|
|
194
|
+
"gray-500": "#6B7280",
|
|
195
|
+
"gray-600": "#4B5563",
|
|
196
|
+
"gray-700": "#374151",
|
|
197
|
+
"gray-800": "#1F2937",
|
|
198
|
+
"gray-900": "#111827",
|
|
199
|
+
// Red
|
|
200
|
+
"red-50": "#FEF2F2",
|
|
201
|
+
"red-100": "#FEE2E2",
|
|
202
|
+
"red-200": "#FECACA",
|
|
203
|
+
"red-300": "#FCA5A5",
|
|
204
|
+
"red-400": "#F87171",
|
|
205
|
+
"red-500": "#EF4444",
|
|
206
|
+
"red-600": "#DC2626",
|
|
207
|
+
"red-700": "#B91C1C",
|
|
208
|
+
"red-800": "#991B1B",
|
|
209
|
+
"red-900": "#7F1D1D",
|
|
210
|
+
// Blue
|
|
211
|
+
"blue-50": "#EFF6FF",
|
|
212
|
+
"blue-100": "#DBEAFE",
|
|
213
|
+
"blue-200": "#BFDBFE",
|
|
214
|
+
"blue-300": "#93C5FD",
|
|
215
|
+
"blue-400": "#60A5FA",
|
|
216
|
+
"blue-500": "#3B82F6",
|
|
217
|
+
"blue-600": "#2563EB",
|
|
218
|
+
"blue-700": "#1D4ED8",
|
|
219
|
+
"blue-800": "#1E40AF",
|
|
220
|
+
"blue-900": "#1E3A8A",
|
|
221
|
+
// Green
|
|
222
|
+
"green-50": "#F0FDF4",
|
|
223
|
+
"green-100": "#DCFCE7",
|
|
224
|
+
"green-200": "#BBF7D0",
|
|
225
|
+
"green-300": "#86EFAC",
|
|
226
|
+
"green-400": "#4ADE80",
|
|
227
|
+
"green-500": "#22C55E",
|
|
228
|
+
"green-600": "#16A34A",
|
|
229
|
+
"green-700": "#15803D",
|
|
230
|
+
"green-800": "#166534",
|
|
231
|
+
"green-900": "#14532D",
|
|
232
|
+
// Yellow
|
|
233
|
+
"yellow-50": "#FEFCE8",
|
|
234
|
+
"yellow-100": "#FEF9C3",
|
|
235
|
+
"yellow-200": "#FEF08A",
|
|
236
|
+
"yellow-300": "#FDE047",
|
|
237
|
+
"yellow-400": "#FACC15",
|
|
238
|
+
"yellow-500": "#EAB308",
|
|
239
|
+
"yellow-600": "#CA8A04",
|
|
240
|
+
"yellow-700": "#A16207",
|
|
241
|
+
"yellow-800": "#854D0E",
|
|
242
|
+
"yellow-900": "#713F12",
|
|
243
|
+
// Purple
|
|
244
|
+
"purple-50": "#FAF5FF",
|
|
245
|
+
"purple-100": "#F3E8FF",
|
|
246
|
+
"purple-200": "#E9D5FF",
|
|
247
|
+
"purple-300": "#D8B4FE",
|
|
248
|
+
"purple-400": "#C084FC",
|
|
249
|
+
"purple-500": "#A855F7",
|
|
250
|
+
"purple-600": "#9333EA",
|
|
251
|
+
"purple-700": "#7E22CE",
|
|
252
|
+
"purple-800": "#6B21A8",
|
|
253
|
+
"purple-900": "#581C87",
|
|
254
|
+
// Pink
|
|
255
|
+
"pink-50": "#FDF2F8",
|
|
256
|
+
"pink-100": "#FCE7F3",
|
|
257
|
+
"pink-200": "#FBCFE8",
|
|
258
|
+
"pink-300": "#F9A8D4",
|
|
259
|
+
"pink-400": "#F472B6",
|
|
260
|
+
"pink-500": "#EC4899",
|
|
261
|
+
"pink-600": "#DB2777",
|
|
262
|
+
"pink-700": "#BE185D",
|
|
263
|
+
"pink-800": "#9D174D",
|
|
264
|
+
"pink-900": "#831843",
|
|
265
|
+
// Orange
|
|
266
|
+
"orange-50": "#FFF7ED",
|
|
267
|
+
"orange-100": "#FFEDD5",
|
|
268
|
+
"orange-200": "#FED7AA",
|
|
269
|
+
"orange-300": "#FDBA74",
|
|
270
|
+
"orange-400": "#FB923C",
|
|
271
|
+
"orange-500": "#F97316",
|
|
272
|
+
"orange-600": "#EA580C",
|
|
273
|
+
"orange-700": "#C2410C",
|
|
274
|
+
"orange-800": "#9A3412",
|
|
275
|
+
"orange-900": "#7C2D12",
|
|
276
|
+
// Indigo
|
|
277
|
+
"indigo-50": "#EEF2FF",
|
|
278
|
+
"indigo-100": "#E0E7FF",
|
|
279
|
+
"indigo-200": "#C7D2FE",
|
|
280
|
+
"indigo-300": "#A5B4FC",
|
|
281
|
+
"indigo-400": "#818CF8",
|
|
282
|
+
"indigo-500": "#6366F1",
|
|
283
|
+
"indigo-600": "#4F46E5",
|
|
284
|
+
"indigo-700": "#4338CA",
|
|
285
|
+
"indigo-800": "#3730A3",
|
|
286
|
+
"indigo-900": "#312E81",
|
|
287
|
+
// Basic colors
|
|
288
|
+
white: "#FFFFFF",
|
|
289
|
+
black: "#000000",
|
|
290
|
+
transparent: "transparent"
|
|
291
|
+
};
|
|
292
|
+
function parseColor(cls, customColors) {
|
|
293
|
+
const getColor = (key) => {
|
|
294
|
+
return customColors?.[key] ?? COLORS[key];
|
|
295
|
+
};
|
|
296
|
+
if (cls.startsWith("bg-")) {
|
|
297
|
+
const colorKey = cls.substring(3);
|
|
298
|
+
const color = getColor(colorKey);
|
|
299
|
+
if (color) {
|
|
300
|
+
return { backgroundColor: color };
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
if (cls.startsWith("text-")) {
|
|
304
|
+
const colorKey = cls.substring(5);
|
|
305
|
+
const color = getColor(colorKey);
|
|
306
|
+
if (color) {
|
|
307
|
+
return { color };
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
if (cls.startsWith("border-") && !cls.match(/^border-[0-9]/)) {
|
|
311
|
+
const colorKey = cls.substring(7);
|
|
312
|
+
const color = getColor(colorKey);
|
|
313
|
+
if (color) {
|
|
314
|
+
return { borderColor: color };
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
return null;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// src/parser/layout.ts
|
|
321
|
+
var DISPLAY_MAP = {
|
|
322
|
+
flex: { display: "flex" },
|
|
323
|
+
hidden: { display: "none" }
|
|
324
|
+
};
|
|
325
|
+
var FLEX_DIRECTION_MAP = {
|
|
326
|
+
"flex-row": { flexDirection: "row" },
|
|
327
|
+
"flex-row-reverse": { flexDirection: "row-reverse" },
|
|
328
|
+
"flex-col": { flexDirection: "column" },
|
|
329
|
+
"flex-col-reverse": { flexDirection: "column-reverse" }
|
|
330
|
+
};
|
|
331
|
+
var FLEX_WRAP_MAP = {
|
|
332
|
+
"flex-wrap": { flexWrap: "wrap" },
|
|
333
|
+
"flex-wrap-reverse": { flexWrap: "wrap-reverse" },
|
|
334
|
+
"flex-nowrap": { flexWrap: "nowrap" }
|
|
335
|
+
};
|
|
336
|
+
var FLEX_MAP = {
|
|
337
|
+
"flex-1": { flex: 1 },
|
|
338
|
+
"flex-auto": { flex: 1 },
|
|
339
|
+
"flex-none": { flex: 0 }
|
|
340
|
+
};
|
|
341
|
+
var GROW_SHRINK_MAP = {
|
|
342
|
+
grow: { flexGrow: 1 },
|
|
343
|
+
"grow-0": { flexGrow: 0 },
|
|
344
|
+
shrink: { flexShrink: 1 },
|
|
345
|
+
"shrink-0": { flexShrink: 0 }
|
|
346
|
+
};
|
|
347
|
+
var JUSTIFY_CONTENT_MAP = {
|
|
348
|
+
"justify-start": { justifyContent: "flex-start" },
|
|
349
|
+
"justify-end": { justifyContent: "flex-end" },
|
|
350
|
+
"justify-center": { justifyContent: "center" },
|
|
351
|
+
"justify-between": { justifyContent: "space-between" },
|
|
352
|
+
"justify-around": { justifyContent: "space-around" },
|
|
353
|
+
"justify-evenly": { justifyContent: "space-evenly" }
|
|
354
|
+
};
|
|
355
|
+
var ALIGN_ITEMS_MAP = {
|
|
356
|
+
"items-start": { alignItems: "flex-start" },
|
|
357
|
+
"items-end": { alignItems: "flex-end" },
|
|
358
|
+
"items-center": { alignItems: "center" },
|
|
359
|
+
"items-baseline": { alignItems: "baseline" },
|
|
360
|
+
"items-stretch": { alignItems: "stretch" }
|
|
361
|
+
};
|
|
362
|
+
var ALIGN_SELF_MAP = {
|
|
363
|
+
"self-auto": { alignSelf: "auto" },
|
|
364
|
+
"self-start": { alignSelf: "flex-start" },
|
|
365
|
+
"self-end": { alignSelf: "flex-end" },
|
|
366
|
+
"self-center": { alignSelf: "center" },
|
|
367
|
+
"self-stretch": { alignSelf: "stretch" },
|
|
368
|
+
"self-baseline": { alignSelf: "baseline" }
|
|
369
|
+
};
|
|
370
|
+
var ALIGN_CONTENT_MAP = {
|
|
371
|
+
"content-start": { alignContent: "flex-start" },
|
|
372
|
+
"content-end": { alignContent: "flex-end" },
|
|
373
|
+
"content-center": { alignContent: "center" },
|
|
374
|
+
"content-between": { alignContent: "space-between" },
|
|
375
|
+
"content-around": { alignContent: "space-around" },
|
|
376
|
+
"content-stretch": { alignContent: "stretch" }
|
|
377
|
+
};
|
|
378
|
+
var POSITION_MAP = {
|
|
379
|
+
absolute: { position: "absolute" },
|
|
380
|
+
relative: { position: "relative" }
|
|
381
|
+
};
|
|
382
|
+
var OVERFLOW_MAP = {
|
|
383
|
+
"overflow-hidden": { overflow: "hidden" },
|
|
384
|
+
"overflow-visible": { overflow: "visible" },
|
|
385
|
+
"overflow-scroll": { overflow: "scroll" }
|
|
386
|
+
};
|
|
387
|
+
function parseLayout(cls) {
|
|
388
|
+
return DISPLAY_MAP[cls] ?? FLEX_DIRECTION_MAP[cls] ?? FLEX_WRAP_MAP[cls] ?? FLEX_MAP[cls] ?? GROW_SHRINK_MAP[cls] ?? JUSTIFY_CONTENT_MAP[cls] ?? ALIGN_ITEMS_MAP[cls] ?? ALIGN_SELF_MAP[cls] ?? ALIGN_CONTENT_MAP[cls] ?? POSITION_MAP[cls] ?? OVERFLOW_MAP[cls] ?? null;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// src/parser/sizing.ts
|
|
392
|
+
var SIZE_SCALE = {
|
|
393
|
+
0: 0,
|
|
394
|
+
0.5: 2,
|
|
395
|
+
1: 4,
|
|
396
|
+
1.5: 6,
|
|
397
|
+
2: 8,
|
|
398
|
+
2.5: 10,
|
|
399
|
+
3: 12,
|
|
400
|
+
3.5: 14,
|
|
401
|
+
4: 16,
|
|
402
|
+
5: 20,
|
|
403
|
+
6: 24,
|
|
404
|
+
7: 28,
|
|
405
|
+
8: 32,
|
|
406
|
+
9: 36,
|
|
407
|
+
10: 40,
|
|
408
|
+
11: 44,
|
|
409
|
+
12: 48,
|
|
410
|
+
14: 56,
|
|
411
|
+
16: 64,
|
|
412
|
+
20: 80,
|
|
413
|
+
24: 96,
|
|
414
|
+
28: 112,
|
|
415
|
+
32: 128,
|
|
416
|
+
36: 144,
|
|
417
|
+
40: 160,
|
|
418
|
+
44: 176,
|
|
419
|
+
48: 192,
|
|
420
|
+
52: 208,
|
|
421
|
+
56: 224,
|
|
422
|
+
60: 240,
|
|
423
|
+
64: 256,
|
|
424
|
+
72: 288,
|
|
425
|
+
80: 320,
|
|
426
|
+
96: 384
|
|
427
|
+
};
|
|
428
|
+
var SIZE_PERCENTAGES = {
|
|
429
|
+
full: "100%",
|
|
430
|
+
"1/2": "50%",
|
|
431
|
+
"1/3": "33.333333%",
|
|
432
|
+
"2/3": "66.666667%",
|
|
433
|
+
"1/4": "25%",
|
|
434
|
+
"2/4": "50%",
|
|
435
|
+
"3/4": "75%",
|
|
436
|
+
"1/5": "20%",
|
|
437
|
+
"2/5": "40%",
|
|
438
|
+
"3/5": "60%",
|
|
439
|
+
"4/5": "80%",
|
|
440
|
+
"1/6": "16.666667%",
|
|
441
|
+
"2/6": "33.333333%",
|
|
442
|
+
"3/6": "50%",
|
|
443
|
+
"4/6": "66.666667%",
|
|
444
|
+
"5/6": "83.333333%"
|
|
445
|
+
};
|
|
446
|
+
function parseArbitrarySize(value) {
|
|
447
|
+
const pxMatch = value.match(/^\[(\d+)(?:px)?\]$/);
|
|
448
|
+
if (pxMatch) {
|
|
449
|
+
return parseInt(pxMatch[1], 10);
|
|
450
|
+
}
|
|
451
|
+
const percentMatch = value.match(/^\[(\d+(?:\.\d+)?)%\]$/);
|
|
452
|
+
if (percentMatch) {
|
|
453
|
+
return `${percentMatch[1]}%`;
|
|
454
|
+
}
|
|
455
|
+
if (value.startsWith("[") && value.endsWith("]")) {
|
|
456
|
+
if (process.env.NODE_ENV !== "production") {
|
|
457
|
+
console.warn(
|
|
458
|
+
`[react-native-tailwind] Unsupported arbitrary size unit: ${value}. Only px and % are supported.`
|
|
459
|
+
);
|
|
460
|
+
}
|
|
461
|
+
return null;
|
|
462
|
+
}
|
|
463
|
+
return null;
|
|
464
|
+
}
|
|
465
|
+
function parseSizing(cls) {
|
|
466
|
+
if (cls.startsWith("w-")) {
|
|
467
|
+
const sizeKey = cls.substring(2);
|
|
468
|
+
const arbitrarySize = parseArbitrarySize(sizeKey);
|
|
469
|
+
if (arbitrarySize !== null) {
|
|
470
|
+
return { width: arbitrarySize };
|
|
471
|
+
}
|
|
472
|
+
const percentage = SIZE_PERCENTAGES[sizeKey];
|
|
473
|
+
if (percentage) {
|
|
474
|
+
return { width: percentage };
|
|
475
|
+
}
|
|
476
|
+
const numericSize = SIZE_SCALE[sizeKey];
|
|
477
|
+
if (numericSize !== void 0) {
|
|
478
|
+
return { width: numericSize };
|
|
479
|
+
}
|
|
480
|
+
if (sizeKey === "auto") {
|
|
481
|
+
return { width: "auto" };
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
if (cls.startsWith("h-")) {
|
|
485
|
+
const sizeKey = cls.substring(2);
|
|
486
|
+
const arbitrarySize = parseArbitrarySize(sizeKey);
|
|
487
|
+
if (arbitrarySize !== null) {
|
|
488
|
+
return { height: arbitrarySize };
|
|
489
|
+
}
|
|
490
|
+
const percentage = SIZE_PERCENTAGES[sizeKey];
|
|
491
|
+
if (percentage) {
|
|
492
|
+
return { height: percentage };
|
|
493
|
+
}
|
|
494
|
+
const numericSize = SIZE_SCALE[sizeKey];
|
|
495
|
+
if (numericSize !== void 0) {
|
|
496
|
+
return { height: numericSize };
|
|
497
|
+
}
|
|
498
|
+
if (sizeKey === "auto") {
|
|
499
|
+
return { height: "auto" };
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
if (cls.startsWith("min-w-")) {
|
|
503
|
+
const sizeKey = cls.substring(6);
|
|
504
|
+
const arbitrarySize = parseArbitrarySize(sizeKey);
|
|
505
|
+
if (arbitrarySize !== null) {
|
|
506
|
+
return { minWidth: arbitrarySize };
|
|
507
|
+
}
|
|
508
|
+
const percentage = SIZE_PERCENTAGES[sizeKey];
|
|
509
|
+
if (percentage) {
|
|
510
|
+
return { minWidth: percentage };
|
|
511
|
+
}
|
|
512
|
+
const numericSize = SIZE_SCALE[sizeKey];
|
|
513
|
+
if (numericSize !== void 0) {
|
|
514
|
+
return { minWidth: numericSize };
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
if (cls.startsWith("min-h-")) {
|
|
518
|
+
const sizeKey = cls.substring(6);
|
|
519
|
+
const arbitrarySize = parseArbitrarySize(sizeKey);
|
|
520
|
+
if (arbitrarySize !== null) {
|
|
521
|
+
return { minHeight: arbitrarySize };
|
|
522
|
+
}
|
|
523
|
+
const percentage = SIZE_PERCENTAGES[sizeKey];
|
|
524
|
+
if (percentage) {
|
|
525
|
+
return { minHeight: percentage };
|
|
526
|
+
}
|
|
527
|
+
const numericSize = SIZE_SCALE[sizeKey];
|
|
528
|
+
if (numericSize !== void 0) {
|
|
529
|
+
return { minHeight: numericSize };
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
if (cls.startsWith("max-w-")) {
|
|
533
|
+
const sizeKey = cls.substring(6);
|
|
534
|
+
const arbitrarySize = parseArbitrarySize(sizeKey);
|
|
535
|
+
if (arbitrarySize !== null) {
|
|
536
|
+
return { maxWidth: arbitrarySize };
|
|
537
|
+
}
|
|
538
|
+
const percentage = SIZE_PERCENTAGES[sizeKey];
|
|
539
|
+
if (percentage) {
|
|
540
|
+
return { maxWidth: percentage };
|
|
541
|
+
}
|
|
542
|
+
const numericSize = SIZE_SCALE[sizeKey];
|
|
543
|
+
if (numericSize !== void 0) {
|
|
544
|
+
return { maxWidth: numericSize };
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
if (cls.startsWith("max-h-")) {
|
|
548
|
+
const sizeKey = cls.substring(6);
|
|
549
|
+
const arbitrarySize = parseArbitrarySize(sizeKey);
|
|
550
|
+
if (arbitrarySize !== null) {
|
|
551
|
+
return { maxHeight: arbitrarySize };
|
|
552
|
+
}
|
|
553
|
+
const percentage = SIZE_PERCENTAGES[sizeKey];
|
|
554
|
+
if (percentage) {
|
|
555
|
+
return { maxHeight: percentage };
|
|
556
|
+
}
|
|
557
|
+
const numericSize = SIZE_SCALE[sizeKey];
|
|
558
|
+
if (numericSize !== void 0) {
|
|
559
|
+
return { maxHeight: numericSize };
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
return null;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
// src/parser/spacing.ts
|
|
566
|
+
var SPACING_SCALE = {
|
|
567
|
+
0: 0,
|
|
568
|
+
0.5: 2,
|
|
569
|
+
1: 4,
|
|
570
|
+
1.5: 6,
|
|
571
|
+
2: 8,
|
|
572
|
+
2.5: 10,
|
|
573
|
+
3: 12,
|
|
574
|
+
3.5: 14,
|
|
575
|
+
4: 16,
|
|
576
|
+
5: 20,
|
|
577
|
+
6: 24,
|
|
578
|
+
7: 28,
|
|
579
|
+
8: 32,
|
|
580
|
+
9: 36,
|
|
581
|
+
10: 40,
|
|
582
|
+
11: 44,
|
|
583
|
+
12: 48,
|
|
584
|
+
14: 56,
|
|
585
|
+
16: 64,
|
|
586
|
+
20: 80,
|
|
587
|
+
24: 96,
|
|
588
|
+
28: 112,
|
|
589
|
+
32: 128,
|
|
590
|
+
36: 144,
|
|
591
|
+
40: 160,
|
|
592
|
+
44: 176,
|
|
593
|
+
48: 192,
|
|
594
|
+
52: 208,
|
|
595
|
+
56: 224,
|
|
596
|
+
60: 240,
|
|
597
|
+
64: 256,
|
|
598
|
+
72: 288,
|
|
599
|
+
80: 320,
|
|
600
|
+
96: 384
|
|
601
|
+
};
|
|
602
|
+
function parseSpacing(cls) {
|
|
603
|
+
if (cls.startsWith("m-") || cls.startsWith("m")) {
|
|
604
|
+
return parseMargin(cls);
|
|
605
|
+
}
|
|
606
|
+
if (cls.startsWith("p-") || cls.startsWith("p")) {
|
|
607
|
+
return parsePadding(cls);
|
|
608
|
+
}
|
|
609
|
+
if (cls.startsWith("gap-")) {
|
|
610
|
+
return parseGap(cls);
|
|
611
|
+
}
|
|
612
|
+
return null;
|
|
613
|
+
}
|
|
614
|
+
function parseMargin(cls) {
|
|
615
|
+
const allMatch = cls.match(/^m-(\d+(?:\.\d+)?)$/);
|
|
616
|
+
if (allMatch) {
|
|
617
|
+
const value = SPACING_SCALE[allMatch[1]];
|
|
618
|
+
if (value !== void 0) {
|
|
619
|
+
return { margin: value };
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
const xMatch = cls.match(/^mx-(\d+(?:\.\d+)?)$/);
|
|
623
|
+
if (xMatch) {
|
|
624
|
+
const value = SPACING_SCALE[xMatch[1]];
|
|
625
|
+
if (value !== void 0) {
|
|
626
|
+
return { marginHorizontal: value };
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
const yMatch = cls.match(/^my-(\d+(?:\.\d+)?)$/);
|
|
630
|
+
if (yMatch) {
|
|
631
|
+
const value = SPACING_SCALE[yMatch[1]];
|
|
632
|
+
if (value !== void 0) {
|
|
633
|
+
return { marginVertical: value };
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
const tMatch = cls.match(/^mt-(\d+(?:\.\d+)?)$/);
|
|
637
|
+
if (tMatch) {
|
|
638
|
+
const value = SPACING_SCALE[tMatch[1]];
|
|
639
|
+
if (value !== void 0) {
|
|
640
|
+
return { marginTop: value };
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
const rMatch = cls.match(/^mr-(\d+(?:\.\d+)?)$/);
|
|
644
|
+
if (rMatch) {
|
|
645
|
+
const value = SPACING_SCALE[rMatch[1]];
|
|
646
|
+
if (value !== void 0) {
|
|
647
|
+
return { marginRight: value };
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
const bMatch = cls.match(/^mb-(\d+(?:\.\d+)?)$/);
|
|
651
|
+
if (bMatch) {
|
|
652
|
+
const value = SPACING_SCALE[bMatch[1]];
|
|
653
|
+
if (value !== void 0) {
|
|
654
|
+
return { marginBottom: value };
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
const lMatch = cls.match(/^ml-(\d+(?:\.\d+)?)$/);
|
|
658
|
+
if (lMatch) {
|
|
659
|
+
const value = SPACING_SCALE[lMatch[1]];
|
|
660
|
+
if (value !== void 0) {
|
|
661
|
+
return { marginLeft: value };
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
return null;
|
|
665
|
+
}
|
|
666
|
+
function parsePadding(cls) {
|
|
667
|
+
const allMatch = cls.match(/^p-(\d+(?:\.\d+)?)$/);
|
|
668
|
+
if (allMatch) {
|
|
669
|
+
const value = SPACING_SCALE[allMatch[1]];
|
|
670
|
+
if (value !== void 0) {
|
|
671
|
+
return { padding: value };
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
const xMatch = cls.match(/^px-(\d+(?:\.\d+)?)$/);
|
|
675
|
+
if (xMatch) {
|
|
676
|
+
const value = SPACING_SCALE[xMatch[1]];
|
|
677
|
+
if (value !== void 0) {
|
|
678
|
+
return { paddingHorizontal: value };
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
const yMatch = cls.match(/^py-(\d+(?:\.\d+)?)$/);
|
|
682
|
+
if (yMatch) {
|
|
683
|
+
const value = SPACING_SCALE[yMatch[1]];
|
|
684
|
+
if (value !== void 0) {
|
|
685
|
+
return { paddingVertical: value };
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
const tMatch = cls.match(/^pt-(\d+(?:\.\d+)?)$/);
|
|
689
|
+
if (tMatch) {
|
|
690
|
+
const value = SPACING_SCALE[tMatch[1]];
|
|
691
|
+
if (value !== void 0) {
|
|
692
|
+
return { paddingTop: value };
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
const rMatch = cls.match(/^pr-(\d+(?:\.\d+)?)$/);
|
|
696
|
+
if (rMatch) {
|
|
697
|
+
const value = SPACING_SCALE[rMatch[1]];
|
|
698
|
+
if (value !== void 0) {
|
|
699
|
+
return { paddingRight: value };
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
const bMatch = cls.match(/^pb-(\d+(?:\.\d+)?)$/);
|
|
703
|
+
if (bMatch) {
|
|
704
|
+
const value = SPACING_SCALE[bMatch[1]];
|
|
705
|
+
if (value !== void 0) {
|
|
706
|
+
return { paddingBottom: value };
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
const lMatch = cls.match(/^pl-(\d+(?:\.\d+)?)$/);
|
|
710
|
+
if (lMatch) {
|
|
711
|
+
const value = SPACING_SCALE[lMatch[1]];
|
|
712
|
+
if (value !== void 0) {
|
|
713
|
+
return { paddingLeft: value };
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
return null;
|
|
717
|
+
}
|
|
718
|
+
function parseGap(cls) {
|
|
719
|
+
const match = cls.match(/^gap-(\d+(?:\.\d+)?)$/);
|
|
720
|
+
if (match) {
|
|
721
|
+
const value = SPACING_SCALE[match[1]];
|
|
722
|
+
if (value !== void 0) {
|
|
723
|
+
return { gap: value };
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
return null;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
// src/parser/typography.ts
|
|
730
|
+
var FONT_SIZES = {
|
|
731
|
+
xs: 12,
|
|
732
|
+
sm: 14,
|
|
733
|
+
base: 16,
|
|
734
|
+
lg: 18,
|
|
735
|
+
xl: 20,
|
|
736
|
+
"2xl": 24,
|
|
737
|
+
"3xl": 30,
|
|
738
|
+
"4xl": 36,
|
|
739
|
+
"5xl": 48,
|
|
740
|
+
"6xl": 60,
|
|
741
|
+
"7xl": 72,
|
|
742
|
+
"8xl": 96,
|
|
743
|
+
"9xl": 128
|
|
744
|
+
};
|
|
745
|
+
function parseTypography(cls) {
|
|
746
|
+
if (cls.startsWith("text-")) {
|
|
747
|
+
const sizeKey = cls.substring(5);
|
|
748
|
+
const fontSize = FONT_SIZES[sizeKey];
|
|
749
|
+
if (fontSize !== void 0) {
|
|
750
|
+
return { fontSize };
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
if (cls === "font-thin") {
|
|
754
|
+
return { fontWeight: "100" };
|
|
755
|
+
}
|
|
756
|
+
if (cls === "font-extralight") {
|
|
757
|
+
return { fontWeight: "200" };
|
|
758
|
+
}
|
|
759
|
+
if (cls === "font-light") {
|
|
760
|
+
return { fontWeight: "300" };
|
|
761
|
+
}
|
|
762
|
+
if (cls === "font-normal") {
|
|
763
|
+
return { fontWeight: "400" };
|
|
764
|
+
}
|
|
765
|
+
if (cls === "font-medium") {
|
|
766
|
+
return { fontWeight: "500" };
|
|
767
|
+
}
|
|
768
|
+
if (cls === "font-semibold") {
|
|
769
|
+
return { fontWeight: "600" };
|
|
770
|
+
}
|
|
771
|
+
if (cls === "font-bold") {
|
|
772
|
+
return { fontWeight: "700" };
|
|
773
|
+
}
|
|
774
|
+
if (cls === "font-extrabold") {
|
|
775
|
+
return { fontWeight: "800" };
|
|
776
|
+
}
|
|
777
|
+
if (cls === "font-black") {
|
|
778
|
+
return { fontWeight: "900" };
|
|
779
|
+
}
|
|
780
|
+
if (cls === "italic") {
|
|
781
|
+
return { fontStyle: "italic" };
|
|
782
|
+
}
|
|
783
|
+
if (cls === "not-italic") {
|
|
784
|
+
return { fontStyle: "normal" };
|
|
785
|
+
}
|
|
786
|
+
if (cls === "text-left") {
|
|
787
|
+
return { textAlign: "left" };
|
|
788
|
+
}
|
|
789
|
+
if (cls === "text-center") {
|
|
790
|
+
return { textAlign: "center" };
|
|
791
|
+
}
|
|
792
|
+
if (cls === "text-right") {
|
|
793
|
+
return { textAlign: "right" };
|
|
794
|
+
}
|
|
795
|
+
if (cls === "text-justify") {
|
|
796
|
+
return { textAlign: "justify" };
|
|
797
|
+
}
|
|
798
|
+
if (cls === "underline") {
|
|
799
|
+
return { textDecorationLine: "underline" };
|
|
800
|
+
}
|
|
801
|
+
if (cls === "line-through") {
|
|
802
|
+
return { textDecorationLine: "line-through" };
|
|
803
|
+
}
|
|
804
|
+
if (cls === "no-underline") {
|
|
805
|
+
return { textDecorationLine: "none" };
|
|
806
|
+
}
|
|
807
|
+
if (cls === "uppercase") {
|
|
808
|
+
return { textTransform: "uppercase" };
|
|
809
|
+
}
|
|
810
|
+
if (cls === "lowercase") {
|
|
811
|
+
return { textTransform: "lowercase" };
|
|
812
|
+
}
|
|
813
|
+
if (cls === "capitalize") {
|
|
814
|
+
return { textTransform: "capitalize" };
|
|
815
|
+
}
|
|
816
|
+
if (cls === "normal-case") {
|
|
817
|
+
return { textTransform: "none" };
|
|
818
|
+
}
|
|
819
|
+
if (cls === "leading-none") {
|
|
820
|
+
return { lineHeight: 16 };
|
|
821
|
+
}
|
|
822
|
+
if (cls === "leading-tight") {
|
|
823
|
+
return { lineHeight: 20 };
|
|
824
|
+
}
|
|
825
|
+
if (cls === "leading-snug") {
|
|
826
|
+
return { lineHeight: 22 };
|
|
827
|
+
}
|
|
828
|
+
if (cls === "leading-normal") {
|
|
829
|
+
return { lineHeight: 24 };
|
|
830
|
+
}
|
|
831
|
+
if (cls === "leading-relaxed") {
|
|
832
|
+
return { lineHeight: 28 };
|
|
833
|
+
}
|
|
834
|
+
if (cls === "leading-loose") {
|
|
835
|
+
return { lineHeight: 32 };
|
|
836
|
+
}
|
|
837
|
+
return null;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
// src/parser/index.ts
|
|
841
|
+
function parseClassName(className, customColors) {
|
|
842
|
+
const classes = className.split(/\s+/).filter(Boolean);
|
|
843
|
+
const style = {};
|
|
844
|
+
for (const cls of classes) {
|
|
845
|
+
const parsedStyle = parseClass(cls, customColors);
|
|
846
|
+
Object.assign(style, parsedStyle);
|
|
847
|
+
}
|
|
848
|
+
return style;
|
|
849
|
+
}
|
|
850
|
+
function parseClass(cls, customColors) {
|
|
851
|
+
const parsers = [
|
|
852
|
+
parseSpacing,
|
|
853
|
+
(cls2) => parseColor(cls2, customColors),
|
|
854
|
+
parseLayout,
|
|
855
|
+
parseTypography,
|
|
856
|
+
parseBorder,
|
|
857
|
+
parseSizing
|
|
858
|
+
];
|
|
859
|
+
for (const parser of parsers) {
|
|
860
|
+
const result = parser(cls);
|
|
861
|
+
if (result !== null) {
|
|
862
|
+
return result;
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
if (process.env.NODE_ENV !== "production") {
|
|
866
|
+
console.warn(`[react-native-tailwind] Unknown class: "${cls}"`);
|
|
867
|
+
}
|
|
868
|
+
return {};
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
// src/utils/styleKey.ts
|
|
872
|
+
function generateStyleKey(className) {
|
|
873
|
+
const classes = className.split(/\s+/).filter(Boolean).sort();
|
|
874
|
+
const key = "_" + classes.join("_").replace(/[^a-zA-Z0-9_]/g, "_").replace(/_+/g, "_");
|
|
875
|
+
return key;
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
// src/babel/config-loader.ts
|
|
879
|
+
var fs = __toESM(require("fs"), 1);
|
|
880
|
+
var path = __toESM(require("path"), 1);
|
|
881
|
+
var configCache = /* @__PURE__ */ new Map();
|
|
882
|
+
function findTailwindConfig(startDir) {
|
|
883
|
+
let currentDir = startDir;
|
|
884
|
+
const root = path.parse(currentDir).root;
|
|
885
|
+
const configNames = [
|
|
886
|
+
"tailwind.config.mjs",
|
|
887
|
+
"tailwind.config.js",
|
|
888
|
+
"tailwind.config.cjs",
|
|
889
|
+
"tailwind.config.ts"
|
|
890
|
+
];
|
|
891
|
+
while (currentDir !== root) {
|
|
892
|
+
for (const configName of configNames) {
|
|
893
|
+
const configPath = path.join(currentDir, configName);
|
|
894
|
+
if (fs.existsSync(configPath)) {
|
|
895
|
+
return configPath;
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
currentDir = path.dirname(currentDir);
|
|
899
|
+
}
|
|
900
|
+
return null;
|
|
901
|
+
}
|
|
902
|
+
function loadTailwindConfig(configPath) {
|
|
903
|
+
if (configCache.has(configPath)) {
|
|
904
|
+
return configCache.get(configPath);
|
|
905
|
+
}
|
|
906
|
+
try {
|
|
907
|
+
const resolvedPath = require.resolve(configPath);
|
|
908
|
+
delete require.cache[resolvedPath];
|
|
909
|
+
const config = require(configPath);
|
|
910
|
+
const resolved = "default" in config ? config.default : config;
|
|
911
|
+
configCache.set(configPath, resolved);
|
|
912
|
+
return resolved;
|
|
913
|
+
} catch (error) {
|
|
914
|
+
if (process.env.NODE_ENV !== "production") {
|
|
915
|
+
console.warn(`[react-native-tailwind] Failed to load config from ${configPath}:`, error);
|
|
916
|
+
}
|
|
917
|
+
configCache.set(configPath, null);
|
|
918
|
+
return null;
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
function flattenColors(colors, prefix = "") {
|
|
922
|
+
const result = {};
|
|
923
|
+
for (const [key, value] of Object.entries(colors)) {
|
|
924
|
+
const newKey = prefix ? `${prefix}-${key}` : key;
|
|
925
|
+
if (typeof value === "string") {
|
|
926
|
+
result[newKey] = value;
|
|
927
|
+
} else if (typeof value === "object" && value !== null) {
|
|
928
|
+
Object.assign(result, flattenColors(value, newKey));
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
return result;
|
|
932
|
+
}
|
|
933
|
+
function extractCustomColors(filename) {
|
|
934
|
+
const projectDir = path.dirname(filename);
|
|
935
|
+
const configPath = findTailwindConfig(projectDir);
|
|
936
|
+
if (!configPath) {
|
|
937
|
+
return {};
|
|
938
|
+
}
|
|
939
|
+
const config = loadTailwindConfig(configPath);
|
|
940
|
+
if (!config?.theme) {
|
|
941
|
+
return {};
|
|
942
|
+
}
|
|
943
|
+
if (config.theme.colors && !config.theme.extend?.colors && process.env.NODE_ENV !== "production") {
|
|
944
|
+
console.warn(
|
|
945
|
+
"[react-native-tailwind] Using theme.colors will override all default colors. Use theme.extend.colors to add custom colors while keeping defaults."
|
|
946
|
+
);
|
|
947
|
+
}
|
|
948
|
+
const colors = config.theme.extend?.colors ?? config.theme.colors ?? {};
|
|
949
|
+
return flattenColors(colors);
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
// src/babel/index.ts
|
|
953
|
+
var SUPPORTED_CLASS_ATTRIBUTES = [
|
|
954
|
+
"className",
|
|
955
|
+
"contentContainerClassName",
|
|
956
|
+
"columnWrapperClassName",
|
|
957
|
+
"ListHeaderComponentClassName",
|
|
958
|
+
"ListFooterComponentClassName"
|
|
959
|
+
];
|
|
960
|
+
function getTargetStyleProp(attributeName) {
|
|
961
|
+
if (attributeName === "contentContainerClassName") {
|
|
962
|
+
return "contentContainerStyle";
|
|
963
|
+
}
|
|
964
|
+
if (attributeName === "columnWrapperClassName") {
|
|
965
|
+
return "columnWrapperStyle";
|
|
966
|
+
}
|
|
967
|
+
if (attributeName === "ListHeaderComponentClassName") {
|
|
968
|
+
return "ListHeaderComponentStyle";
|
|
969
|
+
}
|
|
970
|
+
if (attributeName === "ListFooterComponentClassName") {
|
|
971
|
+
return "ListFooterComponentStyle";
|
|
972
|
+
}
|
|
973
|
+
return "style";
|
|
974
|
+
}
|
|
975
|
+
function reactNativeTailwindBabelPlugin({
|
|
976
|
+
types: t
|
|
977
|
+
}) {
|
|
978
|
+
return {
|
|
979
|
+
name: "react-native-tailwind",
|
|
980
|
+
visitor: {
|
|
981
|
+
Program: {
|
|
982
|
+
enter(_path, state) {
|
|
983
|
+
state.styleRegistry = /* @__PURE__ */ new Map();
|
|
984
|
+
state.hasClassNames = false;
|
|
985
|
+
state.hasStyleSheetImport = false;
|
|
986
|
+
state.customColors = extractCustomColors(state.file.opts.filename ?? "");
|
|
987
|
+
},
|
|
988
|
+
exit(path2, state) {
|
|
989
|
+
if (!state.hasClassNames || state.styleRegistry.size === 0) {
|
|
990
|
+
return;
|
|
991
|
+
}
|
|
992
|
+
if (!state.hasStyleSheetImport) {
|
|
993
|
+
addStyleSheetImport(path2, t);
|
|
994
|
+
}
|
|
995
|
+
injectStyles(path2, state.styleRegistry, t);
|
|
996
|
+
}
|
|
997
|
+
},
|
|
998
|
+
// Check if StyleSheet is already imported
|
|
999
|
+
ImportDeclaration(path2, state) {
|
|
1000
|
+
const node = path2.node;
|
|
1001
|
+
if (node.source.value === "react-native") {
|
|
1002
|
+
const specifiers = node.specifiers;
|
|
1003
|
+
const hasStyleSheet = specifiers.some((spec) => {
|
|
1004
|
+
if (t.isImportSpecifier(spec) && t.isIdentifier(spec.imported)) {
|
|
1005
|
+
return spec.imported.name === "StyleSheet";
|
|
1006
|
+
}
|
|
1007
|
+
return false;
|
|
1008
|
+
});
|
|
1009
|
+
if (hasStyleSheet) {
|
|
1010
|
+
state.hasStyleSheetImport = true;
|
|
1011
|
+
} else {
|
|
1012
|
+
node.specifiers.push(t.importSpecifier(t.identifier("StyleSheet"), t.identifier("StyleSheet")));
|
|
1013
|
+
state.hasStyleSheetImport = true;
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
},
|
|
1017
|
+
JSXAttribute(path2, state) {
|
|
1018
|
+
const node = path2.node;
|
|
1019
|
+
const attributeName = node.name.name;
|
|
1020
|
+
if (!SUPPORTED_CLASS_ATTRIBUTES.includes(attributeName)) {
|
|
1021
|
+
return;
|
|
1022
|
+
}
|
|
1023
|
+
const value = node.value;
|
|
1024
|
+
if (!t.isStringLiteral(value)) {
|
|
1025
|
+
if (process.env.NODE_ENV !== "production") {
|
|
1026
|
+
const filename = state.file.opts.filename ?? "unknown";
|
|
1027
|
+
const targetStyleProp2 = getTargetStyleProp(attributeName);
|
|
1028
|
+
console.warn(
|
|
1029
|
+
`[react-native-tailwind] Dynamic ${attributeName} values are not supported at ${filename}. Use the ${targetStyleProp2} prop for dynamic values.`
|
|
1030
|
+
);
|
|
1031
|
+
}
|
|
1032
|
+
return;
|
|
1033
|
+
}
|
|
1034
|
+
const className = value.value.trim();
|
|
1035
|
+
if (!className) {
|
|
1036
|
+
path2.remove();
|
|
1037
|
+
return;
|
|
1038
|
+
}
|
|
1039
|
+
state.hasClassNames = true;
|
|
1040
|
+
const styleObject = parseClassName2(className, state.customColors);
|
|
1041
|
+
const styleKey = generateStyleKey2(className);
|
|
1042
|
+
state.styleRegistry.set(styleKey, styleObject);
|
|
1043
|
+
const targetStyleProp = getTargetStyleProp(attributeName);
|
|
1044
|
+
const parent = path2.parent;
|
|
1045
|
+
const styleAttribute = parent.attributes.find(
|
|
1046
|
+
(attr) => t.isJSXAttribute(attr) && attr.name.name === targetStyleProp
|
|
1047
|
+
);
|
|
1048
|
+
if (styleAttribute) {
|
|
1049
|
+
mergeStyleAttribute(path2, styleAttribute, styleKey, t);
|
|
1050
|
+
} else {
|
|
1051
|
+
replaceWithStyleAttribute(path2, styleKey, targetStyleProp, t);
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
};
|
|
1056
|
+
}
|
|
1057
|
+
function addStyleSheetImport(path2, t) {
|
|
1058
|
+
const importDeclaration = t.importDeclaration(
|
|
1059
|
+
[t.importSpecifier(t.identifier("StyleSheet"), t.identifier("StyleSheet"))],
|
|
1060
|
+
t.stringLiteral("react-native")
|
|
1061
|
+
);
|
|
1062
|
+
path2.unshiftContainer("body", importDeclaration);
|
|
1063
|
+
}
|
|
1064
|
+
function replaceWithStyleAttribute(classNamePath, styleKey, targetStyleProp, t) {
|
|
1065
|
+
const styleAttribute = t.jsxAttribute(
|
|
1066
|
+
t.jsxIdentifier(targetStyleProp),
|
|
1067
|
+
t.jsxExpressionContainer(t.memberExpression(t.identifier("styles"), t.identifier(styleKey)))
|
|
1068
|
+
);
|
|
1069
|
+
classNamePath.replaceWith(styleAttribute);
|
|
1070
|
+
}
|
|
1071
|
+
function mergeStyleAttribute(classNamePath, styleAttribute, styleKey, t) {
|
|
1072
|
+
const existingStyle = styleAttribute.value.expression;
|
|
1073
|
+
const styleArray = t.arrayExpression([
|
|
1074
|
+
t.memberExpression(t.identifier("styles"), t.identifier(styleKey)),
|
|
1075
|
+
existingStyle
|
|
1076
|
+
]);
|
|
1077
|
+
styleAttribute.value = t.jsxExpressionContainer(styleArray);
|
|
1078
|
+
classNamePath.remove();
|
|
1079
|
+
}
|
|
1080
|
+
function injectStyles(path2, styleRegistry, t) {
|
|
1081
|
+
const styleProperties = [];
|
|
1082
|
+
for (const [key, styleObject] of styleRegistry) {
|
|
1083
|
+
const properties = Object.entries(styleObject).map(([styleProp, styleValue]) => {
|
|
1084
|
+
let valueNode;
|
|
1085
|
+
if (typeof styleValue === "number") {
|
|
1086
|
+
valueNode = t.numericLiteral(styleValue);
|
|
1087
|
+
} else if (typeof styleValue === "string") {
|
|
1088
|
+
valueNode = t.stringLiteral(styleValue);
|
|
1089
|
+
} else {
|
|
1090
|
+
valueNode = t.valueToNode(styleValue);
|
|
1091
|
+
}
|
|
1092
|
+
return t.objectProperty(t.identifier(styleProp), valueNode);
|
|
1093
|
+
});
|
|
1094
|
+
styleProperties.push(t.objectProperty(t.identifier(key), t.objectExpression(properties)));
|
|
1095
|
+
}
|
|
1096
|
+
const styleSheet = t.variableDeclaration("const", [
|
|
1097
|
+
t.variableDeclarator(
|
|
1098
|
+
t.identifier("styles"),
|
|
1099
|
+
t.callExpression(t.memberExpression(t.identifier("StyleSheet"), t.identifier("create")), [
|
|
1100
|
+
t.objectExpression(styleProperties)
|
|
1101
|
+
])
|
|
1102
|
+
)
|
|
1103
|
+
]);
|
|
1104
|
+
path2.pushContainer("body", styleSheet);
|
|
1105
|
+
}
|
|
1106
|
+
function parseClassName2(className, customColors) {
|
|
1107
|
+
return parseClassName(className, customColors);
|
|
1108
|
+
}
|
|
1109
|
+
function generateStyleKey2(className) {
|
|
1110
|
+
return generateStyleKey(className);
|
|
1111
|
+
}
|