@mgcrea/react-native-tailwind 0.13.0 → 0.15.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 +33 -30
- package/dist/babel/config-loader.d.ts +10 -0
- package/dist/babel/config-loader.test.ts +75 -21
- package/dist/babel/config-loader.ts +100 -2
- package/dist/babel/index.cjs +439 -46
- package/dist/babel/plugin/state.d.ts +4 -0
- package/dist/babel/plugin/state.ts +8 -0
- package/dist/babel/plugin/visitors/className.test.ts +313 -0
- package/dist/babel/plugin/visitors/className.ts +36 -8
- package/dist/babel/plugin/visitors/imports.ts +16 -1
- package/dist/babel/plugin/visitors/program.ts +19 -2
- package/dist/babel/plugin/visitors/tw.test.ts +151 -0
- package/dist/babel/utils/directionalModifierProcessing.d.ts +34 -0
- package/dist/babel/utils/directionalModifierProcessing.ts +99 -0
- package/dist/babel/utils/styleInjection.d.ts +16 -0
- package/dist/babel/utils/styleInjection.ts +138 -7
- package/dist/babel/utils/twProcessing.d.ts +2 -0
- package/dist/babel/utils/twProcessing.ts +92 -3
- package/dist/parser/borders.js +1 -1
- package/dist/parser/borders.test.js +1 -1
- package/dist/parser/index.d.ts +3 -2
- package/dist/parser/index.js +1 -1
- package/dist/parser/layout.d.ts +3 -1
- package/dist/parser/layout.js +1 -1
- package/dist/parser/layout.test.js +1 -1
- package/dist/parser/modifiers.d.ts +32 -2
- package/dist/parser/modifiers.js +1 -1
- package/dist/parser/modifiers.test.js +1 -1
- package/dist/parser/sizing.d.ts +3 -1
- package/dist/parser/sizing.js +1 -1
- package/dist/parser/sizing.test.js +1 -1
- package/dist/parser/spacing.d.ts +4 -2
- package/dist/parser/spacing.js +1 -1
- package/dist/parser/spacing.test.js +1 -1
- package/dist/parser/transforms.d.ts +3 -1
- package/dist/parser/transforms.js +1 -1
- package/dist/parser/transforms.test.js +1 -1
- package/dist/parser/typography.test.js +1 -1
- package/dist/runtime.cjs +1 -1
- package/dist/runtime.cjs.map +3 -3
- package/dist/runtime.d.ts +2 -0
- package/dist/runtime.js +1 -1
- package/dist/runtime.js.map +3 -3
- package/dist/runtime.test.js +1 -1
- package/package.json +6 -6
- package/src/babel/config-loader.test.ts +75 -21
- package/src/babel/config-loader.ts +100 -2
- package/src/babel/plugin/state.ts +8 -0
- package/src/babel/plugin/visitors/className.test.ts +313 -0
- package/src/babel/plugin/visitors/className.ts +36 -8
- package/src/babel/plugin/visitors/imports.ts +16 -1
- package/src/babel/plugin/visitors/program.ts +19 -2
- package/src/babel/plugin/visitors/tw.test.ts +151 -0
- package/src/babel/utils/directionalModifierProcessing.ts +99 -0
- package/src/babel/utils/styleInjection.ts +138 -7
- package/src/babel/utils/twProcessing.ts +92 -3
- package/src/parser/borders.test.ts +104 -0
- package/src/parser/borders.ts +50 -7
- package/src/parser/index.ts +8 -5
- package/src/parser/layout.test.ts +168 -0
- package/src/parser/layout.ts +107 -8
- package/src/parser/modifiers.test.ts +206 -0
- package/src/parser/modifiers.ts +62 -3
- package/src/parser/sizing.test.ts +56 -0
- package/src/parser/sizing.ts +20 -15
- package/src/parser/spacing.test.ts +123 -0
- package/src/parser/spacing.ts +30 -15
- package/src/parser/transforms.test.ts +57 -0
- package/src/parser/transforms.ts +7 -3
- package/src/parser/typography.test.ts +8 -0
- package/src/parser/typography.ts +4 -0
- package/src/runtime.test.ts +149 -0
- package/src/runtime.ts +53 -1
package/src/runtime.test.ts
CHANGED
|
@@ -209,6 +209,155 @@ describe("runtime", () => {
|
|
|
209
209
|
backgroundColor: "#007AFF",
|
|
210
210
|
});
|
|
211
211
|
});
|
|
212
|
+
|
|
213
|
+
it("should set custom fontFamily", () => {
|
|
214
|
+
setConfig({
|
|
215
|
+
theme: {
|
|
216
|
+
extend: {
|
|
217
|
+
fontFamily: {
|
|
218
|
+
display: "Inter",
|
|
219
|
+
body: ["Roboto", "sans-serif"], // Array format - takes first value
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
const theme = getCustomTheme();
|
|
226
|
+
expect(theme.fontFamily).toEqual({
|
|
227
|
+
display: "Inter",
|
|
228
|
+
body: "Roboto",
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
it("should set custom fontSize", () => {
|
|
233
|
+
setConfig({
|
|
234
|
+
theme: {
|
|
235
|
+
extend: {
|
|
236
|
+
fontSize: {
|
|
237
|
+
tiny: 10,
|
|
238
|
+
small: "12px",
|
|
239
|
+
medium: 16,
|
|
240
|
+
large: "24",
|
|
241
|
+
},
|
|
242
|
+
},
|
|
243
|
+
},
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
const theme = getCustomTheme();
|
|
247
|
+
expect(theme.fontSize).toEqual({
|
|
248
|
+
tiny: 10,
|
|
249
|
+
small: 12,
|
|
250
|
+
medium: 16,
|
|
251
|
+
large: 24,
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
it("should set custom spacing", () => {
|
|
256
|
+
setConfig({
|
|
257
|
+
theme: {
|
|
258
|
+
extend: {
|
|
259
|
+
spacing: {
|
|
260
|
+
xs: 4,
|
|
261
|
+
sm: "8px",
|
|
262
|
+
md: 16,
|
|
263
|
+
lg: "2rem", // 2rem = 32px
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
const theme = getCustomTheme();
|
|
270
|
+
expect(theme.spacing).toEqual({
|
|
271
|
+
xs: 4,
|
|
272
|
+
sm: 8,
|
|
273
|
+
md: 16,
|
|
274
|
+
lg: 32,
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
it("should use custom fontSize in parsing", () => {
|
|
279
|
+
setConfig({
|
|
280
|
+
theme: {
|
|
281
|
+
extend: {
|
|
282
|
+
fontSize: {
|
|
283
|
+
tiny: 10,
|
|
284
|
+
},
|
|
285
|
+
},
|
|
286
|
+
},
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
const result = tw`text-tiny`;
|
|
290
|
+
expect(result?.style).toEqual({
|
|
291
|
+
fontSize: 10,
|
|
292
|
+
});
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
it("should use custom spacing in parsing", () => {
|
|
296
|
+
setConfig({
|
|
297
|
+
theme: {
|
|
298
|
+
extend: {
|
|
299
|
+
spacing: {
|
|
300
|
+
xs: 4,
|
|
301
|
+
},
|
|
302
|
+
},
|
|
303
|
+
},
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
const result = tw`m-xs p-xs`;
|
|
307
|
+
expect(result?.style).toEqual({
|
|
308
|
+
margin: 4,
|
|
309
|
+
padding: 4,
|
|
310
|
+
});
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
it("should reset fontSize and spacing when config is cleared", () => {
|
|
314
|
+
setConfig({
|
|
315
|
+
theme: {
|
|
316
|
+
extend: {
|
|
317
|
+
fontSize: { tiny: 10 },
|
|
318
|
+
spacing: { xs: 4 },
|
|
319
|
+
},
|
|
320
|
+
},
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
let theme = getCustomTheme();
|
|
324
|
+
expect(theme.fontSize).toEqual({ tiny: 10 });
|
|
325
|
+
expect(theme.spacing).toEqual({ xs: 4 });
|
|
326
|
+
|
|
327
|
+
setConfig({});
|
|
328
|
+
|
|
329
|
+
theme = getCustomTheme();
|
|
330
|
+
expect(theme.fontSize).toEqual({});
|
|
331
|
+
expect(theme.spacing).toEqual({});
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
it("should handle all theme extensions together", () => {
|
|
335
|
+
setConfig({
|
|
336
|
+
theme: {
|
|
337
|
+
extend: {
|
|
338
|
+
colors: { primary: "#007AFF" },
|
|
339
|
+
fontFamily: { display: "Inter" },
|
|
340
|
+
fontSize: { tiny: 10 },
|
|
341
|
+
spacing: { xs: 4 },
|
|
342
|
+
},
|
|
343
|
+
},
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
const theme = getCustomTheme();
|
|
347
|
+
expect(theme.colors).toEqual({ primary: "#007AFF" });
|
|
348
|
+
expect(theme.fontFamily).toEqual({ display: "Inter" });
|
|
349
|
+
expect(theme.fontSize).toEqual({ tiny: 10 });
|
|
350
|
+
expect(theme.spacing).toEqual({ xs: 4 });
|
|
351
|
+
|
|
352
|
+
// Test that parsing uses all of them
|
|
353
|
+
const result = tw`bg-primary font-display text-tiny m-xs`;
|
|
354
|
+
expect(result?.style).toEqual({
|
|
355
|
+
backgroundColor: "#007AFF",
|
|
356
|
+
fontFamily: "Inter",
|
|
357
|
+
fontSize: 10,
|
|
358
|
+
margin: 4,
|
|
359
|
+
});
|
|
360
|
+
});
|
|
212
361
|
});
|
|
213
362
|
|
|
214
363
|
describe("cache", () => {
|
package/src/runtime.ts
CHANGED
|
@@ -12,12 +12,19 @@ export type RuntimeConfig = {
|
|
|
12
12
|
extend?: {
|
|
13
13
|
colors?: Record<string, string | Record<string, string>>;
|
|
14
14
|
fontFamily?: Record<string, string | string[]>;
|
|
15
|
+
fontSize?: Record<string, string | number>;
|
|
16
|
+
spacing?: Record<string, string | number>;
|
|
15
17
|
};
|
|
16
18
|
};
|
|
17
19
|
};
|
|
18
20
|
|
|
19
21
|
// Global custom theme configuration
|
|
20
|
-
const globalCustomTheme: CustomTheme = {
|
|
22
|
+
const globalCustomTheme: CustomTheme = {
|
|
23
|
+
colors: {},
|
|
24
|
+
fontFamily: {},
|
|
25
|
+
fontSize: {},
|
|
26
|
+
spacing: {},
|
|
27
|
+
};
|
|
21
28
|
|
|
22
29
|
// Simple memoization cache
|
|
23
30
|
const styleCache = new Map<string, TwStyle>();
|
|
@@ -72,6 +79,51 @@ export function setConfig(config: RuntimeConfig): void {
|
|
|
72
79
|
globalCustomTheme.fontFamily = {};
|
|
73
80
|
}
|
|
74
81
|
|
|
82
|
+
// Extract custom fontSize
|
|
83
|
+
if (config.theme?.extend?.fontSize) {
|
|
84
|
+
const fontSizeResult: Record<string, number> = {};
|
|
85
|
+
for (const [key, value] of Object.entries(config.theme.extend.fontSize)) {
|
|
86
|
+
if (typeof value === "number") {
|
|
87
|
+
fontSizeResult[key] = value;
|
|
88
|
+
} else if (typeof value === "string") {
|
|
89
|
+
// Parse string values like "18px" or "18" to number
|
|
90
|
+
const parsed = parseFloat(value.replace(/px$/, ""));
|
|
91
|
+
if (!isNaN(parsed)) {
|
|
92
|
+
fontSizeResult[key] = parsed;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
globalCustomTheme.fontSize = fontSizeResult;
|
|
97
|
+
} else {
|
|
98
|
+
globalCustomTheme.fontSize = {};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Extract custom spacing
|
|
102
|
+
if (config.theme?.extend?.spacing) {
|
|
103
|
+
const spacingResult: Record<string, number> = {};
|
|
104
|
+
for (const [key, value] of Object.entries(config.theme.extend.spacing)) {
|
|
105
|
+
if (typeof value === "number") {
|
|
106
|
+
spacingResult[key] = value;
|
|
107
|
+
} else if (typeof value === "string") {
|
|
108
|
+
// Parse string values: "18rem" -> 288, "16px" -> 16, "16" -> 16
|
|
109
|
+
let parsed: number;
|
|
110
|
+
if (value.endsWith("rem")) {
|
|
111
|
+
// Convert rem to px (1rem = 16px)
|
|
112
|
+
parsed = parseFloat(value.replace(/rem$/, "")) * 16;
|
|
113
|
+
} else {
|
|
114
|
+
// Parse px or unitless values
|
|
115
|
+
parsed = parseFloat(value.replace(/px$/, ""));
|
|
116
|
+
}
|
|
117
|
+
if (!isNaN(parsed)) {
|
|
118
|
+
spacingResult[key] = parsed;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
globalCustomTheme.spacing = spacingResult;
|
|
123
|
+
} else {
|
|
124
|
+
globalCustomTheme.spacing = {};
|
|
125
|
+
}
|
|
126
|
+
|
|
75
127
|
// Clear cache when config changes
|
|
76
128
|
styleCache.clear();
|
|
77
129
|
}
|