@mgcrea/react-native-tailwind 0.6.1 → 0.7.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.
Files changed (40) hide show
  1. package/README.md +404 -0
  2. package/dist/babel/config-loader.ts +1 -23
  3. package/dist/babel/index.cjs +227 -60
  4. package/dist/babel/index.d.ts +27 -2
  5. package/dist/babel/index.test.ts +268 -0
  6. package/dist/babel/index.ts +352 -44
  7. package/dist/index.d.ts +3 -0
  8. package/dist/index.js +1 -1
  9. package/dist/parser/__snapshots__/colors.test.js.snap +242 -90
  10. package/dist/parser/__snapshots__/transforms.test.js.snap +58 -0
  11. package/dist/parser/colors.js +1 -1
  12. package/dist/runtime.cjs +2 -0
  13. package/dist/runtime.cjs.map +7 -0
  14. package/dist/runtime.d.ts +139 -0
  15. package/dist/runtime.js +2 -0
  16. package/dist/runtime.js.map +7 -0
  17. package/dist/runtime.test.js +1 -0
  18. package/dist/stubs/tw.d.ts +60 -0
  19. package/dist/stubs/tw.js +1 -0
  20. package/dist/utils/flattenColors.d.ts +16 -0
  21. package/dist/utils/flattenColors.js +1 -0
  22. package/dist/utils/flattenColors.test.js +1 -0
  23. package/dist/utils/modifiers.d.ts +29 -0
  24. package/dist/utils/modifiers.js +1 -0
  25. package/dist/utils/modifiers.test.js +1 -0
  26. package/dist/utils/styleKey.test.js +1 -0
  27. package/package.json +15 -3
  28. package/src/babel/config-loader.ts +1 -23
  29. package/src/babel/index.test.ts +268 -0
  30. package/src/babel/index.ts +352 -44
  31. package/src/index.ts +5 -0
  32. package/src/parser/colors.ts +8 -22
  33. package/src/runtime.test.ts +325 -0
  34. package/src/runtime.ts +280 -0
  35. package/src/stubs/tw.ts +80 -0
  36. package/src/utils/flattenColors.test.ts +361 -0
  37. package/src/utils/flattenColors.ts +32 -0
  38. package/src/utils/modifiers.test.ts +286 -0
  39. package/src/utils/modifiers.ts +63 -0
  40. package/src/utils/styleKey.test.ts +168 -0
@@ -548,20 +548,28 @@ var TAILWIND_PALETTES = {
548
548
  }
549
549
  };
550
550
 
551
- // src/parser/colors.ts
552
- function flattenColors() {
553
- const flat = {};
554
- for (const [colorName, shades] of Object.entries(TAILWIND_PALETTES)) {
555
- for (const [shade, hex] of Object.entries(shades)) {
556
- flat[`${colorName}-${shade}`] = hex;
551
+ // src/utils/flattenColors.ts
552
+ function flattenColors(colors, prefix = "") {
553
+ const result = {};
554
+ for (const [key, value] of Object.entries(colors)) {
555
+ const newKey = prefix ? `${prefix}-${key}` : key;
556
+ if (typeof value === "string") {
557
+ result[newKey] = value;
558
+ } else if (typeof value === "object" && value !== null) {
559
+ Object.assign(result, flattenColors(value, newKey));
557
560
  }
558
561
  }
559
- flat.white = "#FFFFFF";
560
- flat.black = "#000000";
561
- flat.transparent = "transparent";
562
- return flat;
562
+ return result;
563
563
  }
564
- var COLORS = flattenColors();
564
+
565
+ // src/parser/colors.ts
566
+ var COLORS = {
567
+ ...flattenColors(TAILWIND_PALETTES),
568
+ // Add basic colors
569
+ white: "#FFFFFF",
570
+ black: "#000000",
571
+ transparent: "transparent"
572
+ };
565
573
  function applyOpacity(hex, opacity) {
566
574
  if (hex === "transparent") {
567
575
  return "transparent";
@@ -1801,18 +1809,6 @@ function loadTailwindConfig(configPath) {
1801
1809
  return null;
1802
1810
  }
1803
1811
  }
1804
- function flattenColors2(colors, prefix = "") {
1805
- const result = {};
1806
- for (const [key, value] of Object.entries(colors)) {
1807
- const newKey = prefix ? `${prefix}-${key}` : key;
1808
- if (typeof value === "string") {
1809
- result[newKey] = value;
1810
- } else if (typeof value === "object" && value !== null) {
1811
- Object.assign(result, flattenColors2(value, newKey));
1812
- }
1813
- }
1814
- return result;
1815
- }
1816
1812
  function extractCustomColors(filename) {
1817
1813
  const projectDir = path.dirname(filename);
1818
1814
  const configPath = findTailwindConfig(projectDir);
@@ -1829,36 +1825,44 @@ function extractCustomColors(filename) {
1829
1825
  );
1830
1826
  }
1831
1827
  const colors = config.theme.extend?.colors ?? config.theme.colors ?? {};
1832
- return flattenColors2(colors);
1828
+ return flattenColors(colors);
1833
1829
  }
1834
1830
 
1835
1831
  // src/babel/index.ts
1836
- var STYLES_IDENTIFIER = "_twStyles";
1837
- var SUPPORTED_CLASS_ATTRIBUTES = [
1832
+ var DEFAULT_STYLES_IDENTIFIER = "_twStyles";
1833
+ var DEFAULT_CLASS_ATTRIBUTES = [
1838
1834
  "className",
1839
- "containerClassName",
1840
1835
  "contentContainerClassName",
1841
1836
  "columnWrapperClassName",
1842
1837
  "ListHeaderComponentClassName",
1843
1838
  "ListFooterComponentClassName"
1844
1839
  ];
1845
- function getTargetStyleProp(attributeName) {
1846
- if (attributeName === "containerClassName") {
1847
- return "containerStyle";
1848
- }
1849
- if (attributeName === "contentContainerClassName") {
1850
- return "contentContainerStyle";
1851
- }
1852
- if (attributeName === "columnWrapperClassName") {
1853
- return "columnWrapperStyle";
1840
+ function buildAttributeMatchers(attributes) {
1841
+ const exactMatches = /* @__PURE__ */ new Set();
1842
+ const patterns = [];
1843
+ for (const attr of attributes) {
1844
+ if (attr.includes("*")) {
1845
+ const regexPattern = "^" + attr.replace(/\*/g, ".*") + "$";
1846
+ patterns.push(new RegExp(regexPattern));
1847
+ } else {
1848
+ exactMatches.add(attr);
1849
+ }
1854
1850
  }
1855
- if (attributeName === "ListHeaderComponentClassName") {
1856
- return "ListHeaderComponentStyle";
1851
+ return { exactMatches, patterns };
1852
+ }
1853
+ function isAttributeSupported(attributeName, exactMatches, patterns) {
1854
+ if (exactMatches.has(attributeName)) {
1855
+ return true;
1857
1856
  }
1858
- if (attributeName === "ListFooterComponentClassName") {
1859
- return "ListFooterComponentStyle";
1857
+ for (const pattern of patterns) {
1858
+ if (pattern.test(attributeName)) {
1859
+ return true;
1860
+ }
1860
1861
  }
1861
- return "style";
1862
+ return false;
1863
+ }
1864
+ function getTargetStyleProp(attributeName) {
1865
+ return attributeName.endsWith("ClassName") ? attributeName.replace("ClassName", "Style") : "style";
1862
1866
  }
1863
1867
  function getComponentModifierSupport(jsxElement, t) {
1864
1868
  if (!t.isJSXOpeningElement(jsxElement)) {
@@ -1912,7 +1916,7 @@ function processTemplateLiteral(node, state, t) {
1912
1916
  const styleKey = generateStyleKey2(cls);
1913
1917
  state.styleRegistry.set(styleKey, styleObject);
1914
1918
  staticParts.push(cls);
1915
- parts.push(t.memberExpression(t.identifier(STYLES_IDENTIFIER), t.identifier(styleKey)));
1919
+ parts.push(t.memberExpression(t.identifier(state.stylesIdentifier), t.identifier(styleKey)));
1916
1920
  }
1917
1921
  }
1918
1922
  if (i < node.expressions.length) {
@@ -1967,7 +1971,7 @@ function processStringOrExpression(node, state, t) {
1967
1971
  const styleObject = parseClassName2(className, state.customColors);
1968
1972
  const styleKey = generateStyleKey2(className);
1969
1973
  state.styleRegistry.set(styleKey, styleObject);
1970
- return t.memberExpression(t.identifier(STYLES_IDENTIFIER), t.identifier(styleKey));
1974
+ return t.memberExpression(t.identifier(state.stylesIdentifier), t.identifier(styleKey));
1971
1975
  }
1972
1976
  if (t.isConditionalExpression(node)) {
1973
1977
  const result = processConditionalExpression(node, state, t);
@@ -1991,7 +1995,7 @@ function processStaticClassNameWithModifiers(className, state, t) {
1991
1995
  const baseStyleObject = parseClassName2(baseClassName, state.customColors);
1992
1996
  const baseStyleKey = generateStyleKey2(baseClassName);
1993
1997
  state.styleRegistry.set(baseStyleKey, baseStyleObject);
1994
- baseStyleExpression = t.memberExpression(t.identifier(STYLES_IDENTIFIER), t.identifier(baseStyleKey));
1998
+ baseStyleExpression = t.memberExpression(t.identifier(state.stylesIdentifier), t.identifier(baseStyleKey));
1995
1999
  }
1996
2000
  const modifiersByType = /* @__PURE__ */ new Map();
1997
2001
  for (const mod of modifierClasses) {
@@ -2016,7 +2020,7 @@ function processStaticClassNameWithModifiers(className, state, t) {
2016
2020
  const conditionalExpression = t.logicalExpression(
2017
2021
  "&&",
2018
2022
  t.identifier(stateProperty),
2019
- t.memberExpression(t.identifier(STYLES_IDENTIFIER), t.identifier(modifierStyleKey))
2023
+ t.memberExpression(t.identifier(state.stylesIdentifier), t.identifier(modifierStyleKey))
2020
2024
  );
2021
2025
  styleArrayElements.push(conditionalExpression);
2022
2026
  }
@@ -2054,9 +2058,53 @@ function createStyleFunction(styleExpression, modifierTypes, t) {
2054
2058
  const param = t.objectPattern(paramProperties);
2055
2059
  return t.arrowFunctionExpression([param], styleExpression);
2056
2060
  }
2057
- function reactNativeTailwindBabelPlugin({
2058
- types: t
2059
- }) {
2061
+ function processTwCall(className, path2, state, t) {
2062
+ const { baseClasses, modifierClasses } = splitModifierClasses(className);
2063
+ const objectProperties = [];
2064
+ if (baseClasses.length > 0) {
2065
+ const baseClassName = baseClasses.join(" ");
2066
+ const baseStyleObject = parseClassName2(baseClassName, state.customColors);
2067
+ const baseStyleKey = generateStyleKey2(baseClassName);
2068
+ state.styleRegistry.set(baseStyleKey, baseStyleObject);
2069
+ objectProperties.push(
2070
+ t.objectProperty(
2071
+ t.identifier("style"),
2072
+ t.memberExpression(t.identifier(state.stylesIdentifier), t.identifier(baseStyleKey))
2073
+ )
2074
+ );
2075
+ } else {
2076
+ objectProperties.push(t.objectProperty(t.identifier("style"), t.objectExpression([])));
2077
+ }
2078
+ const modifiersByType = /* @__PURE__ */ new Map();
2079
+ for (const mod of modifierClasses) {
2080
+ if (!modifiersByType.has(mod.modifier)) {
2081
+ modifiersByType.set(mod.modifier, []);
2082
+ }
2083
+ const modGroup = modifiersByType.get(mod.modifier);
2084
+ if (modGroup) {
2085
+ modGroup.push(mod);
2086
+ }
2087
+ }
2088
+ for (const [modifierType, modifiers] of modifiersByType) {
2089
+ const modifierClassNames = modifiers.map((m) => m.baseClass).join(" ");
2090
+ const modifierStyleObject = parseClassName2(modifierClassNames, state.customColors);
2091
+ const modifierStyleKey = generateStyleKey2(`${modifierType}_${modifierClassNames}`);
2092
+ state.styleRegistry.set(modifierStyleKey, modifierStyleObject);
2093
+ const propertyName = `${modifierType}Style`;
2094
+ objectProperties.push(
2095
+ t.objectProperty(
2096
+ t.identifier(propertyName),
2097
+ t.memberExpression(t.identifier(state.stylesIdentifier), t.identifier(modifierStyleKey))
2098
+ )
2099
+ );
2100
+ }
2101
+ const twStyleObject = t.objectExpression(objectProperties);
2102
+ path2.replaceWith(twStyleObject);
2103
+ }
2104
+ function reactNativeTailwindBabelPlugin({ types: t }, options) {
2105
+ const attributes = options?.attributes ?? [...DEFAULT_CLASS_ATTRIBUTES];
2106
+ const { exactMatches, patterns } = buildAttributeMatchers(attributes);
2107
+ const stylesIdentifier = options?.stylesIdentifier ?? DEFAULT_STYLES_IDENTIFIER;
2060
2108
  return {
2061
2109
  name: "react-native-tailwind",
2062
2110
  visitor: {
@@ -2065,19 +2113,27 @@ function reactNativeTailwindBabelPlugin({
2065
2113
  state.styleRegistry = /* @__PURE__ */ new Map();
2066
2114
  state.hasClassNames = false;
2067
2115
  state.hasStyleSheetImport = false;
2116
+ state.supportedAttributes = exactMatches;
2117
+ state.attributePatterns = patterns;
2118
+ state.stylesIdentifier = stylesIdentifier;
2119
+ state.twImportNames = /* @__PURE__ */ new Set();
2120
+ state.hasTwImport = false;
2068
2121
  state.customColors = extractCustomColors(state.file.opts.filename ?? "");
2069
2122
  },
2070
2123
  exit(path2, state) {
2124
+ if (state.hasTwImport) {
2125
+ removeTwImports(path2, t);
2126
+ }
2071
2127
  if (!state.hasClassNames || state.styleRegistry.size === 0) {
2072
2128
  return;
2073
2129
  }
2074
2130
  if (!state.hasStyleSheetImport) {
2075
2131
  addStyleSheetImport(path2, t);
2076
2132
  }
2077
- injectStyles(path2, state.styleRegistry, t);
2133
+ injectStylesAtTop(path2, state.styleRegistry, state.stylesIdentifier, t);
2078
2134
  }
2079
2135
  },
2080
- // Check if StyleSheet is already imported
2136
+ // Check if StyleSheet is already imported and track tw/twStyle imports
2081
2137
  ImportDeclaration(path2, state) {
2082
2138
  const node = path2.node;
2083
2139
  if (node.source.value === "react-native") {
@@ -2095,11 +2151,91 @@ function reactNativeTailwindBabelPlugin({
2095
2151
  state.hasStyleSheetImport = true;
2096
2152
  }
2097
2153
  }
2154
+ if (node.source.value === "@mgcrea/react-native-tailwind") {
2155
+ const specifiers = node.specifiers;
2156
+ specifiers.forEach((spec) => {
2157
+ if (t.isImportSpecifier(spec) && t.isIdentifier(spec.imported)) {
2158
+ const importedName = spec.imported.name;
2159
+ if (importedName === "tw" || importedName === "twStyle") {
2160
+ const localName = spec.local.name;
2161
+ state.twImportNames.add(localName);
2162
+ state.hasTwImport = true;
2163
+ }
2164
+ }
2165
+ });
2166
+ }
2167
+ },
2168
+ // Handle tw`...` tagged template expressions
2169
+ TaggedTemplateExpression(path2, state) {
2170
+ const node = path2.node;
2171
+ if (!t.isIdentifier(node.tag)) {
2172
+ return;
2173
+ }
2174
+ const tagName = node.tag.name;
2175
+ if (!state.twImportNames.has(tagName)) {
2176
+ return;
2177
+ }
2178
+ const quasi = node.quasi;
2179
+ if (!t.isTemplateLiteral(quasi)) {
2180
+ return;
2181
+ }
2182
+ if (quasi.expressions.length > 0) {
2183
+ if (process.env.NODE_ENV !== "production") {
2184
+ console.warn(
2185
+ `[react-native-tailwind] Dynamic tw\`...\` with interpolations is not supported at ${state.file.opts.filename ?? "unknown"}. Use style prop for dynamic values.`
2186
+ );
2187
+ }
2188
+ return;
2189
+ }
2190
+ const className = quasi.quasis[0]?.value.cooked?.trim() ?? "";
2191
+ if (!className) {
2192
+ path2.replaceWith(
2193
+ t.objectExpression([t.objectProperty(t.identifier("style"), t.objectExpression([]))])
2194
+ );
2195
+ return;
2196
+ }
2197
+ state.hasClassNames = true;
2198
+ processTwCall(className, path2, state, t);
2199
+ },
2200
+ // Handle twStyle('...') call expressions
2201
+ CallExpression(path2, state) {
2202
+ const node = path2.node;
2203
+ if (!t.isIdentifier(node.callee)) {
2204
+ return;
2205
+ }
2206
+ const calleeName = node.callee.name;
2207
+ if (!state.twImportNames.has(calleeName)) {
2208
+ return;
2209
+ }
2210
+ if (node.arguments.length !== 1) {
2211
+ if (process.env.NODE_ENV !== "production") {
2212
+ console.warn(
2213
+ `[react-native-tailwind] twStyle() expects exactly one argument at ${state.file.opts.filename ?? "unknown"}`
2214
+ );
2215
+ }
2216
+ return;
2217
+ }
2218
+ const arg = node.arguments[0];
2219
+ if (!t.isStringLiteral(arg)) {
2220
+ if (process.env.NODE_ENV !== "production") {
2221
+ console.warn(
2222
+ `[react-native-tailwind] twStyle() only supports static string literals at ${state.file.opts.filename ?? "unknown"}. Use style prop for dynamic values.`
2223
+ );
2224
+ }
2225
+ return;
2226
+ }
2227
+ const className = arg.value.trim();
2228
+ if (!className) {
2229
+ path2.replaceWith(t.identifier("undefined"));
2230
+ return;
2231
+ }
2232
+ state.hasClassNames = true;
2233
+ processTwCall(className, path2, state, t);
2098
2234
  },
2099
2235
  JSXAttribute(path2, state) {
2100
2236
  const node = path2.node;
2101
2237
  const attributeName = node.name.name;
2102
- if (!SUPPORTED_CLASS_ATTRIBUTES.includes(attributeName)) {
2238
+ if (!isAttributeSupported(attributeName, state.supportedAttributes, state.attributePatterns)) {
2103
2239
  return;
2104
2240
  }
2105
2241
  const value = node.value;
@@ -2182,9 +2318,9 @@ function reactNativeTailwindBabelPlugin({
2182
2318
  (attr) => t.isJSXAttribute(attr) && attr.name.name === targetStyleProp
2183
2319
  );
2184
2320
  if (styleAttribute) {
2185
- mergeStyleAttribute(path2, styleAttribute, styleKey, t);
2321
+ mergeStyleAttribute(path2, styleAttribute, styleKey, state.stylesIdentifier, t);
2186
2322
  } else {
2187
- replaceWithStyleAttribute(path2, styleKey, targetStyleProp, t);
2323
+ replaceWithStyleAttribute(path2, styleKey, targetStyleProp, state.stylesIdentifier, t);
2188
2324
  }
2189
2325
  return;
2190
2326
  }
@@ -2233,17 +2369,39 @@ function addStyleSheetImport(path2, t) {
2233
2369
  );
2234
2370
  path2.unshiftContainer("body", importDeclaration);
2235
2371
  }
2236
- function replaceWithStyleAttribute(classNamePath, styleKey, targetStyleProp, t) {
2372
+ function removeTwImports(path2, t) {
2373
+ path2.traverse({
2374
+ ImportDeclaration(importPath) {
2375
+ const node = importPath.node;
2376
+ if (node.source.value !== "@mgcrea/react-native-tailwind") {
2377
+ return;
2378
+ }
2379
+ const remainingSpecifiers = node.specifiers.filter((spec) => {
2380
+ if (t.isImportSpecifier(spec) && t.isIdentifier(spec.imported)) {
2381
+ const importedName = spec.imported.name;
2382
+ return importedName !== "tw" && importedName !== "twStyle";
2383
+ }
2384
+ return true;
2385
+ });
2386
+ if (remainingSpecifiers.length === 0) {
2387
+ importPath.remove();
2388
+ } else if (remainingSpecifiers.length < node.specifiers.length) {
2389
+ node.specifiers = remainingSpecifiers;
2390
+ }
2391
+ }
2392
+ });
2393
+ }
2394
+ function replaceWithStyleAttribute(classNamePath, styleKey, targetStyleProp, stylesIdentifier, t) {
2237
2395
  const styleAttribute = t.jsxAttribute(
2238
2396
  t.jsxIdentifier(targetStyleProp),
2239
- t.jsxExpressionContainer(t.memberExpression(t.identifier(STYLES_IDENTIFIER), t.identifier(styleKey)))
2397
+ t.jsxExpressionContainer(t.memberExpression(t.identifier(stylesIdentifier), t.identifier(styleKey)))
2240
2398
  );
2241
2399
  classNamePath.replaceWith(styleAttribute);
2242
2400
  }
2243
- function mergeStyleAttribute(classNamePath, styleAttribute, styleKey, t) {
2401
+ function mergeStyleAttribute(classNamePath, styleAttribute, styleKey, stylesIdentifier, t) {
2244
2402
  const existingStyle = styleAttribute.value.expression;
2245
2403
  const styleArray = t.arrayExpression([
2246
- t.memberExpression(t.identifier(STYLES_IDENTIFIER), t.identifier(styleKey)),
2404
+ t.memberExpression(t.identifier(stylesIdentifier), t.identifier(styleKey)),
2247
2405
  existingStyle
2248
2406
  ]);
2249
2407
  styleAttribute.value = t.jsxExpressionContainer(styleArray);
@@ -2292,7 +2450,7 @@ function mergeStyleFunctionAttribute(classNamePath, styleAttribute, styleFunctio
2292
2450
  }
2293
2451
  classNamePath.remove();
2294
2452
  }
2295
- function injectStyles(path2, styleRegistry, t) {
2453
+ function injectStylesAtTop(path2, styleRegistry, stylesIdentifier, t) {
2296
2454
  const styleProperties = [];
2297
2455
  for (const [key, styleObject] of styleRegistry) {
2298
2456
  const properties = Object.entries(styleObject).map(([styleProp, styleValue]) => {
@@ -2310,13 +2468,22 @@ function injectStyles(path2, styleRegistry, t) {
2310
2468
  }
2311
2469
  const styleSheet = t.variableDeclaration("const", [
2312
2470
  t.variableDeclarator(
2313
- t.identifier(STYLES_IDENTIFIER),
2471
+ t.identifier(stylesIdentifier),
2314
2472
  t.callExpression(t.memberExpression(t.identifier("StyleSheet"), t.identifier("create")), [
2315
2473
  t.objectExpression(styleProperties)
2316
2474
  ])
2317
2475
  )
2318
2476
  ]);
2319
- path2.pushContainer("body", styleSheet);
2477
+ const body = path2.node.body;
2478
+ let insertIndex = 0;
2479
+ for (let i = 0; i < body.length; i++) {
2480
+ if (t.isImportDeclaration(body[i])) {
2481
+ insertIndex = i + 1;
2482
+ } else {
2483
+ break;
2484
+ }
2485
+ }
2486
+ body.splice(insertIndex, 0, styleSheet);
2320
2487
  }
2321
2488
  function parseClassName2(className, customColors) {
2322
2489
  return parseClassName(className, customColors);
@@ -5,13 +5,38 @@
5
5
  import type { PluginObj, PluginPass } from "@babel/core";
6
6
  import * as BabelTypes from "@babel/types";
7
7
  import { StyleObject } from "src/types.js";
8
+ /**
9
+ * Plugin options
10
+ */
11
+ export type PluginOptions = {
12
+ /**
13
+ * List of JSX attribute names to transform (in addition to or instead of 'className')
14
+ * Supports exact matches and glob patterns:
15
+ * - Exact: 'className', 'containerClassName'
16
+ * - Glob: '*ClassName' (matches any attribute ending in 'ClassName')
17
+ *
18
+ * @default ['className', 'contentContainerClassName', 'columnWrapperClassName', 'ListHeaderComponentClassName', 'ListFooterComponentClassName']
19
+ */
20
+ attributes?: string[];
21
+ /**
22
+ * Custom identifier name for the generated StyleSheet constant
23
+ *
24
+ * @default '_twStyles'
25
+ */
26
+ stylesIdentifier?: string;
27
+ };
8
28
  type PluginState = PluginPass & {
9
29
  styleRegistry: Map<string, StyleObject>;
10
30
  hasClassNames: boolean;
11
31
  hasStyleSheetImport: boolean;
12
32
  customColors: Record<string, string>;
33
+ supportedAttributes: Set<string>;
34
+ attributePatterns: RegExp[];
35
+ stylesIdentifier: string;
36
+ twImportNames: Set<string>;
37
+ hasTwImport: boolean;
13
38
  };
14
- export default function reactNativeTailwindBabelPlugin({ types: t, }: {
39
+ export default function reactNativeTailwindBabelPlugin({ types: t }: {
15
40
  types: typeof BabelTypes;
16
- }): PluginObj<PluginState>;
41
+ }, options?: PluginOptions): PluginObj<PluginState>;
17
42
  export {};