1- /* eslint-disable @typescript-eslint/no-unsafe-argument */
2- /* eslint-disable @typescript-eslint/no-unsafe-call */
3- /* eslint-disable @typescript-eslint/no-unsafe-member-access */
4- /* eslint-disable @typescript-eslint/no-explicit-any */
5- /* eslint-disable @typescript-eslint/no-unsafe-assignment */
6-
71/**
82 * Babel plugin for react-native-tailwind
93 * Transforms className props to style props at compile time
@@ -29,6 +23,7 @@ import { createStyleFunction, processStaticClassNameWithModifiers } from "./util
2923import { addStyleSheetImport , injectStylesAtTop } from "./utils/styleInjection.js" ;
3024import {
3125 addOrMergePlaceholderTextColorProp ,
26+ findStyleAttribute ,
3227 mergeDynamicStyleAttribute ,
3328 mergeStyleAttribute ,
3429 mergeStyleFunctionAttribute ,
@@ -128,13 +123,13 @@ export default function reactNativeTailwindBabelPlugin(
128123 } ,
129124
130125 // Check if StyleSheet is already imported and track tw/twStyle imports
131- ImportDeclaration ( path : NodePath , state : PluginState ) {
132- const node = path . node as any ;
126+ ImportDeclaration ( path , state ) {
127+ const node = path . node ;
133128
134129 // Track react-native StyleSheet import
135130 if ( node . source . value === "react-native" ) {
136131 const specifiers = node . specifiers ;
137- const hasStyleSheet = specifiers . some ( ( spec : any ) => {
132+ const hasStyleSheet = specifiers . some ( ( spec ) => {
138133 if ( t . isImportSpecifier ( spec ) && t . isIdentifier ( spec . imported ) ) {
139134 return spec . imported . name === "StyleSheet" ;
140135 }
@@ -153,7 +148,7 @@ export default function reactNativeTailwindBabelPlugin(
153148 // Track tw/twStyle imports from main package (for compile-time transformation)
154149 if ( node . source . value === "@mgcrea/react-native-tailwind" ) {
155150 const specifiers = node . specifiers ;
156- specifiers . forEach ( ( spec : any ) => {
151+ specifiers . forEach ( ( spec ) => {
157152 if ( t . isImportSpecifier ( spec ) && t . isIdentifier ( spec . imported ) ) {
158153 const importedName = spec . imported . name ;
159154 if ( importedName === "tw" || importedName === "twStyle" ) {
@@ -168,8 +163,8 @@ export default function reactNativeTailwindBabelPlugin(
168163 } ,
169164
170165 // Handle tw`...` tagged template expressions
171- TaggedTemplateExpression ( path : NodePath , state : PluginState ) {
172- const node = path . node as any ;
166+ TaggedTemplateExpression ( path , state ) {
167+ const node = path . node ;
173168
174169 // Check if the tag is a tracked tw import
175170 if ( ! t . isIdentifier ( node . tag ) ) {
@@ -215,8 +210,8 @@ export default function reactNativeTailwindBabelPlugin(
215210 } ,
216211
217212 // Handle twStyle('...') call expressions
218- CallExpression ( path : NodePath , state : PluginState ) {
219- const node = path . node as any ;
213+ CallExpression ( path , state ) {
214+ const node = path . node ;
220215
221216 // Check if the callee is a tracked twStyle import
222217 if ( ! t . isIdentifier ( node . callee ) ) {
@@ -264,8 +259,14 @@ export default function reactNativeTailwindBabelPlugin(
264259 processTwCall ( className , path , state , parseClassName , generateStyleKey , splitModifierClasses , t ) ;
265260 } ,
266261
267- JSXAttribute ( path : NodePath , state : PluginState ) {
268- const node = path . node as any ;
262+ JSXAttribute ( path , state ) {
263+ const node = path . node ;
264+
265+ // Ensure we have a JSXIdentifier name (not JSXNamespacedName)
266+ if ( ! t . isJSXIdentifier ( node . name ) ) {
267+ return ;
268+ }
269+
269270 const attributeName = node . name . name ;
270271
271272 // Only process configured className-like attributes
@@ -300,7 +301,7 @@ export default function reactNativeTailwindBabelPlugin(
300301 // Handle placeholder modifiers first (they generate placeholderTextColor prop, not style)
301302 if ( placeholderModifiers . length > 0 ) {
302303 // Check if this is a TextInput component (placeholder only works on TextInput)
303- const jsxOpeningElement = path . parent ;
304+ const jsxOpeningElement = path . parent as BabelTypes . JSXOpeningElement ;
304305 const componentSupport = getComponentModifierSupport ( jsxOpeningElement , t ) ;
305306
306307 if ( componentSupport ?. supportedModifiers . includes ( "placeholder" ) ) {
@@ -309,8 +310,7 @@ export default function reactNativeTailwindBabelPlugin(
309310
310311 if ( placeholderColor ) {
311312 // Add or merge placeholderTextColor prop
312- const parent = path . parent as any ;
313- addOrMergePlaceholderTextColorProp ( parent , placeholderColor , t ) ;
313+ addOrMergePlaceholderTextColorProp ( jsxOpeningElement , placeholderColor , t ) ;
314314 }
315315 } else {
316316 // Warn if placeholder modifier used on non-TextInput element
@@ -370,10 +370,7 @@ export default function reactNativeTailwindBabelPlugin(
370370 const modifierTypes = Array . from ( new Set ( supportedModifierClasses . map ( ( m ) => m . modifier ) ) ) ;
371371 const styleFunctionExpression = createStyleFunction ( styleExpression , modifierTypes , t ) ;
372372
373- const parent = path . parent as any ;
374- const styleAttribute = parent . attributes . find (
375- ( attr : any ) => t . isJSXAttribute ( attr ) && attr . name . name === targetStyleProp ,
376- ) ;
373+ const styleAttribute = findStyleAttribute ( path , targetStyleProp , t ) ;
377374
378375 if ( styleAttribute ) {
379376 mergeStyleFunctionAttribute ( path , styleAttribute , styleFunctionExpression , t ) ;
@@ -395,10 +392,7 @@ export default function reactNativeTailwindBabelPlugin(
395392 const modifierTypes = usedModifiers ;
396393 const styleFunctionExpression = createStyleFunction ( styleExpression , modifierTypes , t ) ;
397394
398- const parent = path . parent as any ;
399- const styleAttribute = parent . attributes . find (
400- ( attr : any ) => t . isJSXAttribute ( attr ) && attr . name . name === targetStyleProp ,
401- ) ;
395+ const styleAttribute = findStyleAttribute ( path , targetStyleProp , t ) ;
402396
403397 if ( styleAttribute ) {
404398 mergeStyleFunctionAttribute ( path , styleAttribute , styleFunctionExpression , t ) ;
@@ -433,10 +427,7 @@ export default function reactNativeTailwindBabelPlugin(
433427 state . styleRegistry . set ( styleKey , styleObject ) ;
434428
435429 // Check if there's already a style prop on this element
436- const parent = path . parent as any ;
437- const styleAttribute = parent . attributes . find (
438- ( attr : any ) => t . isJSXAttribute ( attr ) && attr . name . name === targetStyleProp ,
439- ) ;
430+ const styleAttribute = findStyleAttribute ( path , targetStyleProp , t ) ;
440431
441432 if ( styleAttribute ) {
442433 // Merge with existing style prop
@@ -465,10 +456,7 @@ export default function reactNativeTailwindBabelPlugin(
465456 state . hasClassNames = true ;
466457
467458 // Check if there's already a style prop on this element
468- const parent = path . parent as any ;
469- const styleAttribute = parent . attributes . find (
470- ( attr : any ) => t . isJSXAttribute ( attr ) && attr . name . name === targetStyleProp ,
471- ) ;
459+ const styleAttribute = findStyleAttribute ( path , targetStyleProp , t ) ;
472460
473461 if ( styleAttribute ) {
474462 // Merge with existing style prop
0 commit comments