@mgcrea/react-native-tailwind 0.11.1 → 0.12.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/dist/babel/index.cjs +189 -20
- package/dist/babel/plugin.test.ts +498 -0
- package/dist/babel/plugin.ts +55 -16
- package/dist/babel/utils/twProcessing.d.ts +8 -1
- package/dist/babel/utils/twProcessing.ts +212 -4
- package/dist/parser/spacing.d.ts +1 -1
- package/dist/parser/spacing.js +1 -1
- package/dist/parser/spacing.test.js +1 -1
- package/dist/runtime.cjs +1 -1
- package/dist/runtime.cjs.map +2 -2
- package/dist/runtime.js +1 -1
- package/dist/runtime.js.map +2 -2
- package/dist/runtime.test.js +1 -1
- package/dist/types/runtime.d.ts +8 -1
- package/package.json +1 -1
- package/src/babel/plugin.test.ts +498 -0
- package/src/babel/plugin.ts +55 -16
- package/src/babel/utils/twProcessing.ts +212 -4
- package/src/parser/spacing.test.ts +62 -0
- package/src/parser/spacing.ts +7 -7
- package/src/runtime.test.ts +4 -1
- package/src/types/runtime.ts +8 -1
package/dist/babel/index.cjs
CHANGED
|
@@ -1194,14 +1194,14 @@ var SPACING_SCALE = {
|
|
|
1194
1194
|
96: 384
|
|
1195
1195
|
};
|
|
1196
1196
|
function parseArbitrarySpacing(value) {
|
|
1197
|
-
const pxMatch = value.match(/^\[(
|
|
1197
|
+
const pxMatch = value.match(/^\[(-?\d+(?:\.\d+)?)(?:px)?\]$/);
|
|
1198
1198
|
if (pxMatch) {
|
|
1199
|
-
return
|
|
1199
|
+
return parseFloat(pxMatch[1]);
|
|
1200
1200
|
}
|
|
1201
1201
|
if (value.startsWith("[") && value.endsWith("]")) {
|
|
1202
1202
|
if (process.env.NODE_ENV !== "production") {
|
|
1203
1203
|
console.warn(
|
|
1204
|
-
`[react-native-tailwind] Unsupported arbitrary spacing value: ${value}. Only px values are supported (e.g., [16px]
|
|
1204
|
+
`[react-native-tailwind] Unsupported arbitrary spacing value: ${value}. Only px values are supported (e.g., [16px], [16], [4.5px], [4.5]).`
|
|
1205
1205
|
);
|
|
1206
1206
|
}
|
|
1207
1207
|
return null;
|
|
@@ -2725,7 +2725,7 @@ function addOrMergePlaceholderTextColorProp(jsxOpeningElement, color, t) {
|
|
|
2725
2725
|
}
|
|
2726
2726
|
|
|
2727
2727
|
// src/babel/utils/twProcessing.ts
|
|
2728
|
-
function processTwCall(className, path2, state, parseClassName2, generateStyleKey2, splitModifierClasses2, t) {
|
|
2728
|
+
function processTwCall(className, path2, state, parseClassName2, generateStyleKey2, splitModifierClasses2, findComponentScope2, t) {
|
|
2729
2729
|
const { baseClasses, modifierClasses: rawModifierClasses } = splitModifierClasses2(className);
|
|
2730
2730
|
const modifierClasses = [];
|
|
2731
2731
|
for (const modifier of rawModifierClasses) {
|
|
@@ -2756,8 +2756,145 @@ function processTwCall(className, path2, state, parseClassName2, generateStyleKe
|
|
|
2756
2756
|
} else {
|
|
2757
2757
|
objectProperties.push(t.objectProperty(t.identifier("style"), t.objectExpression([])));
|
|
2758
2758
|
}
|
|
2759
|
+
const colorSchemeModifiers = modifierClasses.filter((m) => isColorSchemeModifier(m.modifier));
|
|
2760
|
+
const platformModifiers = modifierClasses.filter((m) => isPlatformModifier(m.modifier));
|
|
2761
|
+
const otherModifiers = modifierClasses.filter(
|
|
2762
|
+
(m) => !isColorSchemeModifier(m.modifier) && !isPlatformModifier(m.modifier)
|
|
2763
|
+
);
|
|
2764
|
+
const hasColorSchemeModifiers = colorSchemeModifiers.length > 0;
|
|
2765
|
+
let componentScope = null;
|
|
2766
|
+
if (hasColorSchemeModifiers) {
|
|
2767
|
+
componentScope = findComponentScope2(path2, t);
|
|
2768
|
+
if (!componentScope) {
|
|
2769
|
+
if (process.env.NODE_ENV !== "production") {
|
|
2770
|
+
console.warn(
|
|
2771
|
+
`[react-native-tailwind] Color scheme modifiers (dark:, light:) in tw/twStyle calls must be used inside a React component. Modifiers will be ignored.`
|
|
2772
|
+
);
|
|
2773
|
+
}
|
|
2774
|
+
} else {
|
|
2775
|
+
state.functionComponentsNeedingColorScheme.add(componentScope);
|
|
2776
|
+
}
|
|
2777
|
+
}
|
|
2778
|
+
if (hasColorSchemeModifiers && componentScope) {
|
|
2779
|
+
const colorSchemeConditionals = processColorSchemeModifiers(
|
|
2780
|
+
colorSchemeModifiers,
|
|
2781
|
+
state,
|
|
2782
|
+
parseClassName2,
|
|
2783
|
+
generateStyleKey2,
|
|
2784
|
+
t
|
|
2785
|
+
);
|
|
2786
|
+
const styleArrayElements = [];
|
|
2787
|
+
if (baseClasses.length > 0) {
|
|
2788
|
+
const baseClassName = baseClasses.join(" ");
|
|
2789
|
+
const baseStyleObject = parseClassName2(baseClassName, state.customTheme);
|
|
2790
|
+
const baseStyleKey = generateStyleKey2(baseClassName);
|
|
2791
|
+
state.styleRegistry.set(baseStyleKey, baseStyleObject);
|
|
2792
|
+
styleArrayElements.push(
|
|
2793
|
+
t.memberExpression(t.identifier(state.stylesIdentifier), t.identifier(baseStyleKey))
|
|
2794
|
+
);
|
|
2795
|
+
}
|
|
2796
|
+
styleArrayElements.push(...colorSchemeConditionals);
|
|
2797
|
+
objectProperties[0] = t.objectProperty(t.identifier("style"), t.arrayExpression(styleArrayElements));
|
|
2798
|
+
const darkModifiers = colorSchemeModifiers.filter((m) => m.modifier === "dark");
|
|
2799
|
+
const lightModifiers = colorSchemeModifiers.filter((m) => m.modifier === "light");
|
|
2800
|
+
if (darkModifiers.length > 0) {
|
|
2801
|
+
const darkClassNames = darkModifiers.map((m) => m.baseClass).join(" ");
|
|
2802
|
+
const darkStyleObject = parseClassName2(darkClassNames, state.customTheme);
|
|
2803
|
+
const darkStyleKey = generateStyleKey2(`dark_${darkClassNames}`);
|
|
2804
|
+
state.styleRegistry.set(darkStyleKey, darkStyleObject);
|
|
2805
|
+
objectProperties.push(
|
|
2806
|
+
t.objectProperty(
|
|
2807
|
+
t.identifier("darkStyle"),
|
|
2808
|
+
t.memberExpression(t.identifier(state.stylesIdentifier), t.identifier(darkStyleKey))
|
|
2809
|
+
)
|
|
2810
|
+
);
|
|
2811
|
+
}
|
|
2812
|
+
if (lightModifiers.length > 0) {
|
|
2813
|
+
const lightClassNames = lightModifiers.map((m) => m.baseClass).join(" ");
|
|
2814
|
+
const lightStyleObject = parseClassName2(lightClassNames, state.customTheme);
|
|
2815
|
+
const lightStyleKey = generateStyleKey2(`light_${lightClassNames}`);
|
|
2816
|
+
state.styleRegistry.set(lightStyleKey, lightStyleObject);
|
|
2817
|
+
objectProperties.push(
|
|
2818
|
+
t.objectProperty(
|
|
2819
|
+
t.identifier("lightStyle"),
|
|
2820
|
+
t.memberExpression(t.identifier(state.stylesIdentifier), t.identifier(lightStyleKey))
|
|
2821
|
+
)
|
|
2822
|
+
);
|
|
2823
|
+
}
|
|
2824
|
+
}
|
|
2825
|
+
const hasPlatformModifiers = platformModifiers.length > 0;
|
|
2826
|
+
if (hasPlatformModifiers) {
|
|
2827
|
+
state.needsPlatformImport = true;
|
|
2828
|
+
const platformSelectExpression = processPlatformModifiers(
|
|
2829
|
+
platformModifiers,
|
|
2830
|
+
state,
|
|
2831
|
+
parseClassName2,
|
|
2832
|
+
generateStyleKey2,
|
|
2833
|
+
t
|
|
2834
|
+
);
|
|
2835
|
+
if (hasColorSchemeModifiers && componentScope) {
|
|
2836
|
+
const styleProperty = objectProperties.find(
|
|
2837
|
+
(prop) => t.isIdentifier(prop.key) && prop.key.name === "style"
|
|
2838
|
+
);
|
|
2839
|
+
if (styleProperty && t.isArrayExpression(styleProperty.value)) {
|
|
2840
|
+
styleProperty.value.elements.push(platformSelectExpression);
|
|
2841
|
+
}
|
|
2842
|
+
} else {
|
|
2843
|
+
const styleArrayElements = [];
|
|
2844
|
+
if (baseClasses.length > 0) {
|
|
2845
|
+
const baseClassName = baseClasses.join(" ");
|
|
2846
|
+
const baseStyleObject = parseClassName2(baseClassName, state.customTheme);
|
|
2847
|
+
const baseStyleKey = generateStyleKey2(baseClassName);
|
|
2848
|
+
state.styleRegistry.set(baseStyleKey, baseStyleObject);
|
|
2849
|
+
styleArrayElements.push(
|
|
2850
|
+
t.memberExpression(t.identifier(state.stylesIdentifier), t.identifier(baseStyleKey))
|
|
2851
|
+
);
|
|
2852
|
+
}
|
|
2853
|
+
styleArrayElements.push(platformSelectExpression);
|
|
2854
|
+
objectProperties[0] = t.objectProperty(t.identifier("style"), t.arrayExpression(styleArrayElements));
|
|
2855
|
+
}
|
|
2856
|
+
const iosModifiers = platformModifiers.filter((m) => m.modifier === "ios");
|
|
2857
|
+
const androidModifiers = platformModifiers.filter((m) => m.modifier === "android");
|
|
2858
|
+
const webModifiers = platformModifiers.filter((m) => m.modifier === "web");
|
|
2859
|
+
if (iosModifiers.length > 0) {
|
|
2860
|
+
const iosClassNames = iosModifiers.map((m) => m.baseClass).join(" ");
|
|
2861
|
+
const iosStyleObject = parseClassName2(iosClassNames, state.customTheme);
|
|
2862
|
+
const iosStyleKey = generateStyleKey2(`ios_${iosClassNames}`);
|
|
2863
|
+
state.styleRegistry.set(iosStyleKey, iosStyleObject);
|
|
2864
|
+
objectProperties.push(
|
|
2865
|
+
t.objectProperty(
|
|
2866
|
+
t.identifier("iosStyle"),
|
|
2867
|
+
t.memberExpression(t.identifier(state.stylesIdentifier), t.identifier(iosStyleKey))
|
|
2868
|
+
)
|
|
2869
|
+
);
|
|
2870
|
+
}
|
|
2871
|
+
if (androidModifiers.length > 0) {
|
|
2872
|
+
const androidClassNames = androidModifiers.map((m) => m.baseClass).join(" ");
|
|
2873
|
+
const androidStyleObject = parseClassName2(androidClassNames, state.customTheme);
|
|
2874
|
+
const androidStyleKey = generateStyleKey2(`android_${androidClassNames}`);
|
|
2875
|
+
state.styleRegistry.set(androidStyleKey, androidStyleObject);
|
|
2876
|
+
objectProperties.push(
|
|
2877
|
+
t.objectProperty(
|
|
2878
|
+
t.identifier("androidStyle"),
|
|
2879
|
+
t.memberExpression(t.identifier(state.stylesIdentifier), t.identifier(androidStyleKey))
|
|
2880
|
+
)
|
|
2881
|
+
);
|
|
2882
|
+
}
|
|
2883
|
+
if (webModifiers.length > 0) {
|
|
2884
|
+
const webClassNames = webModifiers.map((m) => m.baseClass).join(" ");
|
|
2885
|
+
const webStyleObject = parseClassName2(webClassNames, state.customTheme);
|
|
2886
|
+
const webStyleKey = generateStyleKey2(`web_${webClassNames}`);
|
|
2887
|
+
state.styleRegistry.set(webStyleKey, webStyleObject);
|
|
2888
|
+
objectProperties.push(
|
|
2889
|
+
t.objectProperty(
|
|
2890
|
+
t.identifier("webStyle"),
|
|
2891
|
+
t.memberExpression(t.identifier(state.stylesIdentifier), t.identifier(webStyleKey))
|
|
2892
|
+
)
|
|
2893
|
+
);
|
|
2894
|
+
}
|
|
2895
|
+
}
|
|
2759
2896
|
const modifiersByType = /* @__PURE__ */ new Map();
|
|
2760
|
-
for (const mod of
|
|
2897
|
+
for (const mod of otherModifiers) {
|
|
2761
2898
|
if (!modifiersByType.has(mod.modifier)) {
|
|
2762
2899
|
modifiersByType.set(mod.modifier, []);
|
|
2763
2900
|
}
|
|
@@ -2876,6 +3013,10 @@ function reactNativeTailwindBabelPlugin({ types: t }, options) {
|
|
|
2876
3013
|
state.twImportNames = /* @__PURE__ */ new Set();
|
|
2877
3014
|
state.hasTwImport = false;
|
|
2878
3015
|
state.functionComponentsNeedingColorScheme = /* @__PURE__ */ new Set();
|
|
3016
|
+
state.hasColorSchemeImport = false;
|
|
3017
|
+
state.colorSchemeLocalIdentifier = void 0;
|
|
3018
|
+
state.needsPlatformImport = false;
|
|
3019
|
+
state.hasPlatformImport = false;
|
|
2879
3020
|
state.customTheme = extractCustomTheme(state.file.opts.filename ?? "");
|
|
2880
3021
|
state.schemeModifierConfig = schemeModifierConfig;
|
|
2881
3022
|
},
|
|
@@ -2934,7 +3075,7 @@ function reactNativeTailwindBabelPlugin({ types: t }, options) {
|
|
|
2934
3075
|
}
|
|
2935
3076
|
state.reactNativeImportPath = path2;
|
|
2936
3077
|
}
|
|
2937
|
-
if (node.source.value === state.colorSchemeImportSource) {
|
|
3078
|
+
if (node.source.value === state.colorSchemeImportSource && node.importKind !== "type") {
|
|
2938
3079
|
const specifiers = node.specifiers;
|
|
2939
3080
|
for (const spec of specifiers) {
|
|
2940
3081
|
if (t.isImportSpecifier(spec) && t.isIdentifier(spec.imported)) {
|
|
@@ -2990,7 +3131,16 @@ function reactNativeTailwindBabelPlugin({ types: t }, options) {
|
|
|
2990
3131
|
return;
|
|
2991
3132
|
}
|
|
2992
3133
|
state.hasClassNames = true;
|
|
2993
|
-
processTwCall(
|
|
3134
|
+
processTwCall(
|
|
3135
|
+
className,
|
|
3136
|
+
path2,
|
|
3137
|
+
state,
|
|
3138
|
+
parseClassName,
|
|
3139
|
+
generateStyleKey,
|
|
3140
|
+
splitModifierClasses,
|
|
3141
|
+
findComponentScope,
|
|
3142
|
+
t
|
|
3143
|
+
);
|
|
2994
3144
|
},
|
|
2995
3145
|
// Handle twStyle('...') call expressions
|
|
2996
3146
|
CallExpression(path2, state) {
|
|
@@ -3025,7 +3175,16 @@ function reactNativeTailwindBabelPlugin({ types: t }, options) {
|
|
|
3025
3175
|
return;
|
|
3026
3176
|
}
|
|
3027
3177
|
state.hasClassNames = true;
|
|
3028
|
-
processTwCall(
|
|
3178
|
+
processTwCall(
|
|
3179
|
+
className,
|
|
3180
|
+
path2,
|
|
3181
|
+
state,
|
|
3182
|
+
parseClassName,
|
|
3183
|
+
generateStyleKey,
|
|
3184
|
+
splitModifierClasses,
|
|
3185
|
+
findComponentScope,
|
|
3186
|
+
t
|
|
3187
|
+
);
|
|
3029
3188
|
},
|
|
3030
3189
|
JSXAttribute(path2, state) {
|
|
3031
3190
|
const node = path2.node;
|
|
@@ -3038,14 +3197,14 @@ function reactNativeTailwindBabelPlugin({ types: t }, options) {
|
|
|
3038
3197
|
}
|
|
3039
3198
|
const value = node.value;
|
|
3040
3199
|
const targetStyleProp = getTargetStyleProp(attributeName);
|
|
3041
|
-
|
|
3042
|
-
const
|
|
3043
|
-
if (!
|
|
3200
|
+
const processStaticClassName = (className) => {
|
|
3201
|
+
const trimmedClassName = className.trim();
|
|
3202
|
+
if (!trimmedClassName) {
|
|
3044
3203
|
path2.remove();
|
|
3045
|
-
return;
|
|
3204
|
+
return true;
|
|
3046
3205
|
}
|
|
3047
3206
|
state.hasClassNames = true;
|
|
3048
|
-
const { baseClasses, modifierClasses: rawModifierClasses } = splitModifierClasses(
|
|
3207
|
+
const { baseClasses, modifierClasses: rawModifierClasses } = splitModifierClasses(trimmedClassName);
|
|
3049
3208
|
const modifierClasses = [];
|
|
3050
3209
|
for (const modifier of rawModifierClasses) {
|
|
3051
3210
|
if (isSchemeModifier(modifier.modifier)) {
|
|
@@ -3169,7 +3328,7 @@ function reactNativeTailwindBabelPlugin({ types: t }, options) {
|
|
|
3169
3328
|
} else {
|
|
3170
3329
|
replaceWithStyleFunctionAttribute(path2, styleFunctionExpression, targetStyleProp, t);
|
|
3171
3330
|
}
|
|
3172
|
-
return;
|
|
3331
|
+
return true;
|
|
3173
3332
|
} else {
|
|
3174
3333
|
}
|
|
3175
3334
|
}
|
|
@@ -3220,7 +3379,7 @@ function reactNativeTailwindBabelPlugin({ types: t }, options) {
|
|
|
3220
3379
|
path2.node.name = t.jsxIdentifier(targetStyleProp);
|
|
3221
3380
|
path2.node.value = t.jsxExpressionContainer(styleExpression);
|
|
3222
3381
|
}
|
|
3223
|
-
return;
|
|
3382
|
+
return true;
|
|
3224
3383
|
}
|
|
3225
3384
|
if (hasStateModifiers) {
|
|
3226
3385
|
const jsxOpeningElement = path2.parent;
|
|
@@ -3258,11 +3417,11 @@ function reactNativeTailwindBabelPlugin({ types: t }, options) {
|
|
|
3258
3417
|
} else {
|
|
3259
3418
|
replaceWithStyleFunctionAttribute(path2, styleFunctionExpression, targetStyleProp, t);
|
|
3260
3419
|
}
|
|
3261
|
-
return;
|
|
3420
|
+
return true;
|
|
3262
3421
|
}
|
|
3263
3422
|
} else {
|
|
3264
3423
|
const styleExpression = processStaticClassNameWithModifiers(
|
|
3265
|
-
|
|
3424
|
+
trimmedClassName,
|
|
3266
3425
|
state,
|
|
3267
3426
|
parseClassName,
|
|
3268
3427
|
generateStyleKey,
|
|
@@ -3277,7 +3436,7 @@ function reactNativeTailwindBabelPlugin({ types: t }, options) {
|
|
|
3277
3436
|
} else {
|
|
3278
3437
|
replaceWithStyleFunctionAttribute(path2, styleFunctionExpression, targetStyleProp, t);
|
|
3279
3438
|
}
|
|
3280
|
-
return;
|
|
3439
|
+
return true;
|
|
3281
3440
|
}
|
|
3282
3441
|
} else {
|
|
3283
3442
|
if (process.env.NODE_ENV !== "production") {
|
|
@@ -3291,7 +3450,7 @@ function reactNativeTailwindBabelPlugin({ types: t }, options) {
|
|
|
3291
3450
|
const classNameForStyle = baseClasses.join(" ");
|
|
3292
3451
|
if (!classNameForStyle) {
|
|
3293
3452
|
path2.remove();
|
|
3294
|
-
return;
|
|
3453
|
+
return true;
|
|
3295
3454
|
}
|
|
3296
3455
|
const styleObject = parseClassName(classNameForStyle, state.customTheme);
|
|
3297
3456
|
const styleKey = generateStyleKey(classNameForStyle);
|
|
@@ -3302,13 +3461,23 @@ function reactNativeTailwindBabelPlugin({ types: t }, options) {
|
|
|
3302
3461
|
} else {
|
|
3303
3462
|
replaceWithStyleAttribute(path2, styleKey, targetStyleProp, state.stylesIdentifier, t);
|
|
3304
3463
|
}
|
|
3305
|
-
return;
|
|
3464
|
+
return true;
|
|
3465
|
+
};
|
|
3466
|
+
if (t.isStringLiteral(value)) {
|
|
3467
|
+
if (processStaticClassName(value.value)) {
|
|
3468
|
+
return;
|
|
3469
|
+
}
|
|
3306
3470
|
}
|
|
3307
3471
|
if (t.isJSXExpressionContainer(value)) {
|
|
3308
3472
|
const expression = value.expression;
|
|
3309
3473
|
if (t.isJSXEmptyExpression(expression)) {
|
|
3310
3474
|
return;
|
|
3311
3475
|
}
|
|
3476
|
+
if (t.isStringLiteral(expression)) {
|
|
3477
|
+
if (processStaticClassName(expression.value)) {
|
|
3478
|
+
return;
|
|
3479
|
+
}
|
|
3480
|
+
}
|
|
3312
3481
|
try {
|
|
3313
3482
|
const componentScope = findComponentScope(path2, t);
|
|
3314
3483
|
const result = processDynamicExpression(
|