@mgcrea/react-native-tailwind 0.10.0 → 0.11.1
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 +159 -13
- package/dist/babel/config-loader.d.ts +12 -3
- package/dist/babel/config-loader.test.ts +14 -12
- package/dist/babel/config-loader.ts +41 -9
- package/dist/babel/index.cjs +91 -54
- package/dist/babel/plugin.d.ts +39 -1
- package/dist/babel/plugin.test.ts +275 -1
- package/dist/babel/plugin.ts +84 -25
- package/dist/babel/utils/colorSchemeModifierProcessing.d.ts +3 -3
- package/dist/babel/utils/colorSchemeModifierProcessing.ts +4 -4
- package/dist/babel/utils/dynamicProcessing.d.ts +5 -5
- package/dist/babel/utils/dynamicProcessing.ts +11 -11
- package/dist/babel/utils/modifierProcessing.d.ts +3 -3
- package/dist/babel/utils/modifierProcessing.ts +5 -5
- package/dist/babel/utils/platformModifierProcessing.d.ts +3 -3
- package/dist/babel/utils/platformModifierProcessing.ts +4 -4
- package/dist/babel/utils/styleInjection.d.ts +5 -3
- package/dist/babel/utils/styleInjection.ts +38 -23
- package/dist/babel/utils/twProcessing.d.ts +3 -3
- package/dist/babel/utils/twProcessing.ts +6 -6
- package/dist/parser/index.d.ts +11 -4
- package/dist/parser/index.js +1 -1
- package/dist/parser/typography.d.ts +3 -1
- package/dist/parser/typography.js +1 -1
- package/dist/runtime.cjs +1 -1
- package/dist/runtime.cjs.map +3 -3
- package/dist/runtime.d.ts +8 -1
- package/dist/runtime.js +1 -1
- package/dist/runtime.js.map +3 -3
- package/dist/runtime.test.js +1 -1
- package/package.json +1 -1
- package/src/babel/config-loader.test.ts +14 -12
- package/src/babel/config-loader.ts +41 -9
- package/src/babel/plugin.test.ts +275 -1
- package/src/babel/plugin.ts +84 -25
- package/src/babel/utils/colorSchemeModifierProcessing.ts +4 -4
- package/src/babel/utils/dynamicProcessing.ts +11 -11
- package/src/babel/utils/modifierProcessing.ts +5 -5
- package/src/babel/utils/platformModifierProcessing.ts +4 -4
- package/src/babel/utils/styleInjection.ts +38 -23
- package/src/babel/utils/twProcessing.ts +6 -6
- package/src/parser/index.ts +16 -8
- package/src/parser/typography.ts +14 -2
- package/src/runtime.test.ts +7 -7
- package/src/runtime.ts +37 -14
package/dist/babel/index.cjs
CHANGED
|
@@ -1678,7 +1678,13 @@ function parseArbitraryLineHeight(value) {
|
|
|
1678
1678
|
}
|
|
1679
1679
|
return null;
|
|
1680
1680
|
}
|
|
1681
|
-
function parseTypography(cls) {
|
|
1681
|
+
function parseTypography(cls, customFontFamily) {
|
|
1682
|
+
const fontFamilyMap = customFontFamily ? {
|
|
1683
|
+
...FONT_FAMILY_MAP,
|
|
1684
|
+
...Object.fromEntries(
|
|
1685
|
+
Object.entries(customFontFamily).map(([key, value]) => [`font-${key}`, { fontFamily: value }])
|
|
1686
|
+
)
|
|
1687
|
+
} : FONT_FAMILY_MAP;
|
|
1682
1688
|
if (cls.startsWith("text-")) {
|
|
1683
1689
|
const sizeKey = cls.substring(5);
|
|
1684
1690
|
const arbitraryValue = parseArbitraryFontSize(sizeKey);
|
|
@@ -1701,7 +1707,7 @@ function parseTypography(cls) {
|
|
|
1701
1707
|
return { lineHeight };
|
|
1702
1708
|
}
|
|
1703
1709
|
}
|
|
1704
|
-
return
|
|
1710
|
+
return fontFamilyMap[cls] ?? FONT_WEIGHT_MAP[cls] ?? FONT_STYLE_MAP[cls] ?? TEXT_ALIGN_MAP[cls] ?? TEXT_DECORATION_MAP[cls] ?? TEXT_TRANSFORM_MAP[cls] ?? LINE_HEIGHT_MAP[cls] ?? TRACKING_MAP[cls] ?? null;
|
|
1705
1711
|
}
|
|
1706
1712
|
|
|
1707
1713
|
// src/parser/placeholder.ts
|
|
@@ -1842,22 +1848,22 @@ function splitModifierClasses(className) {
|
|
|
1842
1848
|
}
|
|
1843
1849
|
|
|
1844
1850
|
// src/parser/index.ts
|
|
1845
|
-
function parseClassName(className,
|
|
1851
|
+
function parseClassName(className, customTheme) {
|
|
1846
1852
|
const classes = className.split(/\s+/).filter(Boolean);
|
|
1847
1853
|
const style = {};
|
|
1848
1854
|
for (const cls of classes) {
|
|
1849
|
-
const parsedStyle = parseClass(cls,
|
|
1855
|
+
const parsedStyle = parseClass(cls, customTheme);
|
|
1850
1856
|
Object.assign(style, parsedStyle);
|
|
1851
1857
|
}
|
|
1852
1858
|
return style;
|
|
1853
1859
|
}
|
|
1854
|
-
function parseClass(cls,
|
|
1860
|
+
function parseClass(cls, customTheme) {
|
|
1855
1861
|
const parsers = [
|
|
1856
1862
|
parseSpacing,
|
|
1857
1863
|
parseBorder,
|
|
1858
|
-
(cls2) => parseColor(cls2,
|
|
1864
|
+
(cls2) => parseColor(cls2, customTheme?.colors),
|
|
1859
1865
|
parseLayout,
|
|
1860
|
-
parseTypography,
|
|
1866
|
+
(cls2) => parseTypography(cls2, customTheme?.fontFamily),
|
|
1861
1867
|
parseSizing,
|
|
1862
1868
|
parseShadow,
|
|
1863
1869
|
parseAspectRatio,
|
|
@@ -1925,15 +1931,15 @@ function loadTailwindConfig(configPath) {
|
|
|
1925
1931
|
return null;
|
|
1926
1932
|
}
|
|
1927
1933
|
}
|
|
1928
|
-
function
|
|
1934
|
+
function extractCustomTheme(filename) {
|
|
1929
1935
|
const projectDir = path.dirname(filename);
|
|
1930
1936
|
const configPath = findTailwindConfig(projectDir);
|
|
1931
1937
|
if (!configPath) {
|
|
1932
|
-
return {};
|
|
1938
|
+
return { colors: {}, fontFamily: {} };
|
|
1933
1939
|
}
|
|
1934
1940
|
const config = loadTailwindConfig(configPath);
|
|
1935
1941
|
if (!config?.theme) {
|
|
1936
|
-
return {};
|
|
1942
|
+
return { colors: {}, fontFamily: {} };
|
|
1937
1943
|
}
|
|
1938
1944
|
if (config.theme.colors && !config.theme.extend?.colors && process.env.NODE_ENV !== "production") {
|
|
1939
1945
|
console.warn(
|
|
@@ -1941,7 +1947,24 @@ function extractCustomColors(filename) {
|
|
|
1941
1947
|
);
|
|
1942
1948
|
}
|
|
1943
1949
|
const colors = config.theme.extend?.colors ?? config.theme.colors ?? {};
|
|
1944
|
-
|
|
1950
|
+
if (config.theme.fontFamily && !config.theme.extend?.fontFamily && process.env.NODE_ENV !== "production") {
|
|
1951
|
+
console.warn(
|
|
1952
|
+
"[react-native-tailwind] Using theme.fontFamily will override all default font families. Use theme.extend.fontFamily to add custom fonts while keeping defaults."
|
|
1953
|
+
);
|
|
1954
|
+
}
|
|
1955
|
+
const fontFamily = config.theme.extend?.fontFamily ?? config.theme.fontFamily ?? {};
|
|
1956
|
+
const fontFamilyResult = {};
|
|
1957
|
+
for (const [key, value] of Object.entries(fontFamily)) {
|
|
1958
|
+
if (Array.isArray(value)) {
|
|
1959
|
+
fontFamilyResult[key] = value[0];
|
|
1960
|
+
} else {
|
|
1961
|
+
fontFamilyResult[key] = value;
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1964
|
+
return {
|
|
1965
|
+
colors: flattenColors(colors),
|
|
1966
|
+
fontFamily: fontFamilyResult
|
|
1967
|
+
};
|
|
1945
1968
|
}
|
|
1946
1969
|
|
|
1947
1970
|
// src/babel/utils/attributeMatchers.ts
|
|
@@ -1997,7 +2020,7 @@ function processColorSchemeModifiers(colorSchemeModifiers, state, parseClassName
|
|
|
1997
2020
|
const conditionalExpressions = [];
|
|
1998
2021
|
for (const [scheme, modifiers] of modifiersByScheme) {
|
|
1999
2022
|
const classNames = modifiers.map((m) => m.baseClass).join(" ");
|
|
2000
|
-
const styleObject = parseClassName2(classNames, state.
|
|
2023
|
+
const styleObject = parseClassName2(classNames, state.customTheme);
|
|
2001
2024
|
const styleKey = generateStyleKey2(`${scheme}_${classNames}`);
|
|
2002
2025
|
state.styleRegistry.set(styleKey, styleObject);
|
|
2003
2026
|
const colorSchemeCheck = t.binaryExpression(
|
|
@@ -2252,7 +2275,7 @@ function processStringOrExpressionHelper(node, state, parseClassName2, generateS
|
|
|
2252
2275
|
if (isSchemeModifier2(modifier.modifier)) {
|
|
2253
2276
|
const expanded = expandSchemeModifier2(
|
|
2254
2277
|
modifier,
|
|
2255
|
-
state.
|
|
2278
|
+
state.customTheme.colors ?? {},
|
|
2256
2279
|
state.schemeModifierConfig.darkSuffix ?? "-dark",
|
|
2257
2280
|
state.schemeModifierConfig.lightSuffix ?? "-light"
|
|
2258
2281
|
);
|
|
@@ -2266,7 +2289,7 @@ function processStringOrExpressionHelper(node, state, parseClassName2, generateS
|
|
|
2266
2289
|
const styleElements = [];
|
|
2267
2290
|
if (baseClasses.length > 0) {
|
|
2268
2291
|
const baseClassName = baseClasses.join(" ");
|
|
2269
|
-
const styleObject = parseClassName2(baseClassName, state.
|
|
2292
|
+
const styleObject = parseClassName2(baseClassName, state.customTheme);
|
|
2270
2293
|
const styleKey = generateStyleKey2(baseClassName);
|
|
2271
2294
|
state.styleRegistry.set(styleKey, styleObject);
|
|
2272
2295
|
styleElements.push(t.memberExpression(t.identifier(state.stylesIdentifier), t.identifier(styleKey)));
|
|
@@ -2373,7 +2396,7 @@ function processStaticClassNameWithModifiers(className, state, parseClassName2,
|
|
|
2373
2396
|
let baseStyleExpression = null;
|
|
2374
2397
|
if (baseClasses.length > 0) {
|
|
2375
2398
|
const baseClassName = baseClasses.join(" ");
|
|
2376
|
-
const baseStyleObject = parseClassName2(baseClassName, state.
|
|
2399
|
+
const baseStyleObject = parseClassName2(baseClassName, state.customTheme);
|
|
2377
2400
|
const baseStyleKey = generateStyleKey2(baseClassName);
|
|
2378
2401
|
state.styleRegistry.set(baseStyleKey, baseStyleObject);
|
|
2379
2402
|
baseStyleExpression = t.memberExpression(t.identifier(state.stylesIdentifier), t.identifier(baseStyleKey));
|
|
@@ -2394,7 +2417,7 @@ function processStaticClassNameWithModifiers(className, state, parseClassName2,
|
|
|
2394
2417
|
}
|
|
2395
2418
|
for (const [modifierType, modifiers] of modifiersByType) {
|
|
2396
2419
|
const modifierClassNames = modifiers.map((m) => m.baseClass).join(" ");
|
|
2397
|
-
const modifierStyleObject = parseClassName2(modifierClassNames, state.
|
|
2420
|
+
const modifierStyleObject = parseClassName2(modifierClassNames, state.customTheme);
|
|
2398
2421
|
const modifierStyleKey = generateStyleKey2(`${modifierType}_${modifierClassNames}`);
|
|
2399
2422
|
state.styleRegistry.set(modifierStyleKey, modifierStyleObject);
|
|
2400
2423
|
const stateProperty = getStatePropertyForModifier(modifierType);
|
|
@@ -2443,7 +2466,7 @@ function processPlatformModifiers(platformModifiers, state, parseClassName2, gen
|
|
|
2443
2466
|
const selectProperties = [];
|
|
2444
2467
|
for (const [platform, modifiers] of modifiersByPlatform) {
|
|
2445
2468
|
const classNames = modifiers.map((m) => m.baseClass).join(" ");
|
|
2446
|
-
const styleObject = parseClassName2(classNames, state.
|
|
2469
|
+
const styleObject = parseClassName2(classNames, state.customTheme);
|
|
2447
2470
|
const styleKey = generateStyleKey2(`${platform}_${classNames}`);
|
|
2448
2471
|
state.styleRegistry.set(styleKey, styleObject);
|
|
2449
2472
|
const styleReference = t.memberExpression(t.identifier(state.stylesIdentifier), t.identifier(styleKey));
|
|
@@ -2495,33 +2518,33 @@ function addPlatformImport(path2, t) {
|
|
|
2495
2518
|
path2.unshiftContainer("body", importDeclaration);
|
|
2496
2519
|
}
|
|
2497
2520
|
}
|
|
2498
|
-
function addColorSchemeImport(path2, t) {
|
|
2521
|
+
function addColorSchemeImport(path2, importSource, hookName, t) {
|
|
2499
2522
|
const body = path2.node.body;
|
|
2500
|
-
let
|
|
2523
|
+
let existingValueImport = null;
|
|
2501
2524
|
for (const statement of body) {
|
|
2502
|
-
if (t.isImportDeclaration(statement) && statement.source.value ===
|
|
2503
|
-
|
|
2504
|
-
|
|
2525
|
+
if (t.isImportDeclaration(statement) && statement.source.value === importSource) {
|
|
2526
|
+
if (statement.importKind !== "type") {
|
|
2527
|
+
existingValueImport = statement;
|
|
2528
|
+
break;
|
|
2529
|
+
}
|
|
2505
2530
|
}
|
|
2506
2531
|
}
|
|
2507
|
-
if (
|
|
2508
|
-
const
|
|
2509
|
-
(spec) => t.isImportSpecifier(spec) && spec.imported.type === "Identifier" && spec.imported.name ===
|
|
2532
|
+
if (existingValueImport) {
|
|
2533
|
+
const hasHook = existingValueImport.specifiers.some(
|
|
2534
|
+
(spec) => t.isImportSpecifier(spec) && spec.imported.type === "Identifier" && spec.imported.name === hookName
|
|
2510
2535
|
);
|
|
2511
|
-
if (!
|
|
2512
|
-
|
|
2513
|
-
t.importSpecifier(t.identifier("useColorScheme"), t.identifier("useColorScheme"))
|
|
2514
|
-
);
|
|
2536
|
+
if (!hasHook) {
|
|
2537
|
+
existingValueImport.specifiers.push(t.importSpecifier(t.identifier(hookName), t.identifier(hookName)));
|
|
2515
2538
|
}
|
|
2516
2539
|
} else {
|
|
2517
2540
|
const importDeclaration = t.importDeclaration(
|
|
2518
|
-
[t.importSpecifier(t.identifier(
|
|
2519
|
-
t.stringLiteral(
|
|
2541
|
+
[t.importSpecifier(t.identifier(hookName), t.identifier(hookName))],
|
|
2542
|
+
t.stringLiteral(importSource)
|
|
2520
2543
|
);
|
|
2521
2544
|
path2.unshiftContainer("body", importDeclaration);
|
|
2522
2545
|
}
|
|
2523
2546
|
}
|
|
2524
|
-
function injectColorSchemeHook(functionPath, colorSchemeVariableName, t) {
|
|
2547
|
+
function injectColorSchemeHook(functionPath, colorSchemeVariableName, hookName, localIdentifier, t) {
|
|
2525
2548
|
let body = functionPath.node.body;
|
|
2526
2549
|
if (!t.isBlockStatement(body)) {
|
|
2527
2550
|
if (t.isArrowFunctionExpression(functionPath.node) && t.isExpression(body)) {
|
|
@@ -2543,10 +2566,11 @@ function injectColorSchemeHook(functionPath, colorSchemeVariableName, t) {
|
|
|
2543
2566
|
if (hasHook) {
|
|
2544
2567
|
return false;
|
|
2545
2568
|
}
|
|
2569
|
+
const identifierToCall = localIdentifier ?? hookName;
|
|
2546
2570
|
const hookCall = t.variableDeclaration("const", [
|
|
2547
2571
|
t.variableDeclarator(
|
|
2548
2572
|
t.identifier(colorSchemeVariableName),
|
|
2549
|
-
t.callExpression(t.identifier(
|
|
2573
|
+
t.callExpression(t.identifier(identifierToCall), [])
|
|
2550
2574
|
)
|
|
2551
2575
|
]);
|
|
2552
2576
|
body.body.unshift(hookCall);
|
|
@@ -2708,7 +2732,7 @@ function processTwCall(className, path2, state, parseClassName2, generateStyleKe
|
|
|
2708
2732
|
if (isSchemeModifier(modifier.modifier)) {
|
|
2709
2733
|
const expanded = expandSchemeModifier(
|
|
2710
2734
|
modifier,
|
|
2711
|
-
state.
|
|
2735
|
+
state.customTheme.colors ?? {},
|
|
2712
2736
|
state.schemeModifierConfig.darkSuffix ?? "-dark",
|
|
2713
2737
|
state.schemeModifierConfig.lightSuffix ?? "-light"
|
|
2714
2738
|
);
|
|
@@ -2720,7 +2744,7 @@ function processTwCall(className, path2, state, parseClassName2, generateStyleKe
|
|
|
2720
2744
|
const objectProperties = [];
|
|
2721
2745
|
if (baseClasses.length > 0) {
|
|
2722
2746
|
const baseClassName = baseClasses.join(" ");
|
|
2723
|
-
const baseStyleObject = parseClassName2(baseClassName, state.
|
|
2747
|
+
const baseStyleObject = parseClassName2(baseClassName, state.customTheme);
|
|
2724
2748
|
const baseStyleKey = generateStyleKey2(baseClassName);
|
|
2725
2749
|
state.styleRegistry.set(baseStyleKey, baseStyleObject);
|
|
2726
2750
|
objectProperties.push(
|
|
@@ -2744,7 +2768,7 @@ function processTwCall(className, path2, state, parseClassName2, generateStyleKe
|
|
|
2744
2768
|
}
|
|
2745
2769
|
for (const [modifierType, modifiers] of modifiersByType) {
|
|
2746
2770
|
const modifierClassNames = modifiers.map((m) => m.baseClass).join(" ");
|
|
2747
|
-
const modifierStyleObject = parseClassName2(modifierClassNames, state.
|
|
2771
|
+
const modifierStyleObject = parseClassName2(modifierClassNames, state.customTheme);
|
|
2748
2772
|
const modifierStyleKey = generateStyleKey2(`${modifierType}_${modifierClassNames}`);
|
|
2749
2773
|
state.styleRegistry.set(modifierStyleKey, modifierStyleObject);
|
|
2750
2774
|
const propertyName = `${modifierType}Style`;
|
|
@@ -2829,6 +2853,8 @@ function reactNativeTailwindBabelPlugin({ types: t }, options) {
|
|
|
2829
2853
|
darkSuffix: options?.schemeModifier?.darkSuffix ?? "-dark",
|
|
2830
2854
|
lightSuffix: options?.schemeModifier?.lightSuffix ?? "-light"
|
|
2831
2855
|
};
|
|
2856
|
+
const colorSchemeImportSource = options?.colorScheme?.importFrom ?? "react-native";
|
|
2857
|
+
const colorSchemeHookName = options?.colorScheme?.importName ?? "useColorScheme";
|
|
2832
2858
|
return {
|
|
2833
2859
|
name: "react-native-tailwind",
|
|
2834
2860
|
visitor: {
|
|
@@ -2842,13 +2868,15 @@ function reactNativeTailwindBabelPlugin({ types: t }, options) {
|
|
|
2842
2868
|
state.hasColorSchemeImport = false;
|
|
2843
2869
|
state.needsColorSchemeImport = false;
|
|
2844
2870
|
state.colorSchemeVariableName = "_twColorScheme";
|
|
2871
|
+
state.colorSchemeImportSource = colorSchemeImportSource;
|
|
2872
|
+
state.colorSchemeHookName = colorSchemeHookName;
|
|
2845
2873
|
state.supportedAttributes = exactMatches;
|
|
2846
2874
|
state.attributePatterns = patterns;
|
|
2847
2875
|
state.stylesIdentifier = stylesIdentifier;
|
|
2848
2876
|
state.twImportNames = /* @__PURE__ */ new Set();
|
|
2849
2877
|
state.hasTwImport = false;
|
|
2850
2878
|
state.functionComponentsNeedingColorScheme = /* @__PURE__ */ new Set();
|
|
2851
|
-
state.
|
|
2879
|
+
state.customTheme = extractCustomTheme(state.file.opts.filename ?? "");
|
|
2852
2880
|
state.schemeModifierConfig = schemeModifierConfig;
|
|
2853
2881
|
},
|
|
2854
2882
|
exit(path2, state) {
|
|
@@ -2865,11 +2893,17 @@ function reactNativeTailwindBabelPlugin({ types: t }, options) {
|
|
|
2865
2893
|
addPlatformImport(path2, t);
|
|
2866
2894
|
}
|
|
2867
2895
|
if (state.needsColorSchemeImport && !state.hasColorSchemeImport) {
|
|
2868
|
-
addColorSchemeImport(path2, t);
|
|
2896
|
+
addColorSchemeImport(path2, state.colorSchemeImportSource, state.colorSchemeHookName, t);
|
|
2869
2897
|
}
|
|
2870
2898
|
if (state.needsColorSchemeImport) {
|
|
2871
2899
|
for (const functionPath of state.functionComponentsNeedingColorScheme) {
|
|
2872
|
-
injectColorSchemeHook(
|
|
2900
|
+
injectColorSchemeHook(
|
|
2901
|
+
functionPath,
|
|
2902
|
+
state.colorSchemeVariableName,
|
|
2903
|
+
state.colorSchemeHookName,
|
|
2904
|
+
state.colorSchemeLocalIdentifier,
|
|
2905
|
+
t
|
|
2906
|
+
);
|
|
2873
2907
|
}
|
|
2874
2908
|
}
|
|
2875
2909
|
injectStylesAtTop(path2, state.styleRegistry, state.stylesIdentifier, t);
|
|
@@ -2892,23 +2926,26 @@ function reactNativeTailwindBabelPlugin({ types: t }, options) {
|
|
|
2892
2926
|
}
|
|
2893
2927
|
return false;
|
|
2894
2928
|
});
|
|
2895
|
-
const hasUseColorScheme = specifiers.some((spec) => {
|
|
2896
|
-
if (t.isImportSpecifier(spec) && t.isIdentifier(spec.imported)) {
|
|
2897
|
-
return spec.imported.name === "useColorScheme";
|
|
2898
|
-
}
|
|
2899
|
-
return false;
|
|
2900
|
-
});
|
|
2901
2929
|
if (hasStyleSheet) {
|
|
2902
2930
|
state.hasStyleSheetImport = true;
|
|
2903
2931
|
}
|
|
2904
2932
|
if (hasPlatform) {
|
|
2905
2933
|
state.hasPlatformImport = true;
|
|
2906
2934
|
}
|
|
2907
|
-
if (hasUseColorScheme) {
|
|
2908
|
-
state.hasColorSchemeImport = true;
|
|
2909
|
-
}
|
|
2910
2935
|
state.reactNativeImportPath = path2;
|
|
2911
2936
|
}
|
|
2937
|
+
if (node.source.value === state.colorSchemeImportSource) {
|
|
2938
|
+
const specifiers = node.specifiers;
|
|
2939
|
+
for (const spec of specifiers) {
|
|
2940
|
+
if (t.isImportSpecifier(spec) && t.isIdentifier(spec.imported)) {
|
|
2941
|
+
if (spec.imported.name === state.colorSchemeHookName) {
|
|
2942
|
+
state.hasColorSchemeImport = true;
|
|
2943
|
+
state.colorSchemeLocalIdentifier = spec.local.name;
|
|
2944
|
+
break;
|
|
2945
|
+
}
|
|
2946
|
+
}
|
|
2947
|
+
}
|
|
2948
|
+
}
|
|
2912
2949
|
if (node.source.value === "@mgcrea/react-native-tailwind") {
|
|
2913
2950
|
const specifiers = node.specifiers;
|
|
2914
2951
|
specifiers.forEach((spec) => {
|
|
@@ -3014,7 +3051,7 @@ function reactNativeTailwindBabelPlugin({ types: t }, options) {
|
|
|
3014
3051
|
if (isSchemeModifier(modifier.modifier)) {
|
|
3015
3052
|
const expanded = expandSchemeModifier(
|
|
3016
3053
|
modifier,
|
|
3017
|
-
state.
|
|
3054
|
+
state.customTheme.colors ?? {},
|
|
3018
3055
|
state.schemeModifierConfig.darkSuffix,
|
|
3019
3056
|
state.schemeModifierConfig.lightSuffix
|
|
3020
3057
|
);
|
|
@@ -3034,7 +3071,7 @@ function reactNativeTailwindBabelPlugin({ types: t }, options) {
|
|
|
3034
3071
|
const componentSupport = getComponentModifierSupport(jsxOpeningElement, t);
|
|
3035
3072
|
if (componentSupport?.supportedModifiers.includes("placeholder")) {
|
|
3036
3073
|
const placeholderClasses = placeholderModifiers.map((m) => m.baseClass).join(" ");
|
|
3037
|
-
const placeholderColor = parsePlaceholderClasses(placeholderClasses, state.
|
|
3074
|
+
const placeholderColor = parsePlaceholderClasses(placeholderClasses, state.customTheme.colors);
|
|
3038
3075
|
if (placeholderColor) {
|
|
3039
3076
|
addOrMergePlaceholderTextColorProp(jsxOpeningElement, placeholderColor, t);
|
|
3040
3077
|
}
|
|
@@ -3070,7 +3107,7 @@ function reactNativeTailwindBabelPlugin({ types: t }, options) {
|
|
|
3070
3107
|
const styleArrayElements = [];
|
|
3071
3108
|
if (hasBaseClasses) {
|
|
3072
3109
|
const baseClassName = baseClasses.join(" ");
|
|
3073
|
-
const baseStyleObject = parseClassName(baseClassName, state.
|
|
3110
|
+
const baseStyleObject = parseClassName(baseClassName, state.customTheme);
|
|
3074
3111
|
const baseStyleKey = generateStyleKey(baseClassName);
|
|
3075
3112
|
state.styleRegistry.set(baseStyleKey, baseStyleObject);
|
|
3076
3113
|
styleArrayElements.push(
|
|
@@ -3110,7 +3147,7 @@ function reactNativeTailwindBabelPlugin({ types: t }, options) {
|
|
|
3110
3147
|
continue;
|
|
3111
3148
|
}
|
|
3112
3149
|
const modifierClassNames = modifiers.map((m) => m.baseClass).join(" ");
|
|
3113
|
-
const modifierStyleObject = parseClassName(modifierClassNames, state.
|
|
3150
|
+
const modifierStyleObject = parseClassName(modifierClassNames, state.customTheme);
|
|
3114
3151
|
const modifierStyleKey = generateStyleKey(`${modifierType}_${modifierClassNames}`);
|
|
3115
3152
|
state.styleRegistry.set(modifierStyleKey, modifierStyleObject);
|
|
3116
3153
|
const stateProperty = getStatePropertyForModifier(modifierType);
|
|
@@ -3140,7 +3177,7 @@ function reactNativeTailwindBabelPlugin({ types: t }, options) {
|
|
|
3140
3177
|
const styleExpressions = [];
|
|
3141
3178
|
if (hasBaseClasses) {
|
|
3142
3179
|
const baseClassName = baseClasses.join(" ");
|
|
3143
|
-
const baseStyleObject = parseClassName(baseClassName, state.
|
|
3180
|
+
const baseStyleObject = parseClassName(baseClassName, state.customTheme);
|
|
3144
3181
|
const baseStyleKey = generateStyleKey(baseClassName);
|
|
3145
3182
|
state.styleRegistry.set(baseStyleKey, baseStyleObject);
|
|
3146
3183
|
styleExpressions.push(
|
|
@@ -3256,7 +3293,7 @@ function reactNativeTailwindBabelPlugin({ types: t }, options) {
|
|
|
3256
3293
|
path2.remove();
|
|
3257
3294
|
return;
|
|
3258
3295
|
}
|
|
3259
|
-
const styleObject = parseClassName(classNameForStyle, state.
|
|
3296
|
+
const styleObject = parseClassName(classNameForStyle, state.customTheme);
|
|
3260
3297
|
const styleKey = generateStyleKey(classNameForStyle);
|
|
3261
3298
|
state.styleRegistry.set(styleKey, styleObject);
|
|
3262
3299
|
const styleAttribute = findStyleAttribute(path2, targetStyleProp, t);
|
package/dist/babel/plugin.d.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import type { NodePath, PluginObj, PluginPass } from "@babel/core";
|
|
6
6
|
import * as BabelTypes from "@babel/types";
|
|
7
7
|
import type { StyleObject } from "../types/core.js";
|
|
8
|
+
import type { CustomTheme } from "./config-loader.js";
|
|
8
9
|
import type { SchemeModifierConfig } from "../types/config.js";
|
|
9
10
|
/**
|
|
10
11
|
* Plugin options
|
|
@@ -40,6 +41,40 @@ export type PluginOptions = {
|
|
|
40
41
|
darkSuffix?: string;
|
|
41
42
|
lightSuffix?: string;
|
|
42
43
|
};
|
|
44
|
+
/**
|
|
45
|
+
* Configuration for color scheme hook import (dark:/light: modifiers)
|
|
46
|
+
*
|
|
47
|
+
* Allows using custom color scheme hooks from theme providers instead of
|
|
48
|
+
* React Native's built-in useColorScheme.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* // Use custom hook from theme provider
|
|
52
|
+
* {
|
|
53
|
+
* importFrom: '@/hooks/useColorScheme',
|
|
54
|
+
* importName: 'useColorScheme'
|
|
55
|
+
* }
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* // Use React Navigation theme
|
|
59
|
+
* {
|
|
60
|
+
* importFrom: '@react-navigation/native',
|
|
61
|
+
* importName: 'useTheme' // You'd wrap this to return ColorSchemeName
|
|
62
|
+
* }
|
|
63
|
+
*
|
|
64
|
+
* @default { importFrom: 'react-native', importName: 'useColorScheme' }
|
|
65
|
+
*/
|
|
66
|
+
colorScheme?: {
|
|
67
|
+
/**
|
|
68
|
+
* Module to import the color scheme hook from
|
|
69
|
+
* @default 'react-native'
|
|
70
|
+
*/
|
|
71
|
+
importFrom?: string;
|
|
72
|
+
/**
|
|
73
|
+
* Name of the hook to import
|
|
74
|
+
* @default 'useColorScheme'
|
|
75
|
+
*/
|
|
76
|
+
importName?: string;
|
|
77
|
+
};
|
|
43
78
|
};
|
|
44
79
|
type PluginState = PluginPass & {
|
|
45
80
|
styleRegistry: Map<string, StyleObject>;
|
|
@@ -50,7 +85,10 @@ type PluginState = PluginPass & {
|
|
|
50
85
|
hasColorSchemeImport: boolean;
|
|
51
86
|
needsColorSchemeImport: boolean;
|
|
52
87
|
colorSchemeVariableName: string;
|
|
53
|
-
|
|
88
|
+
colorSchemeImportSource: string;
|
|
89
|
+
colorSchemeHookName: string;
|
|
90
|
+
colorSchemeLocalIdentifier?: string;
|
|
91
|
+
customTheme: CustomTheme;
|
|
54
92
|
schemeModifierConfig: SchemeModifierConfig;
|
|
55
93
|
supportedAttributes: Set<string>;
|
|
56
94
|
attributePatterns: RegExp[];
|