@@ -84,6 +84,10 @@ module.exports = {
8484 const isStrictMode = filename . endsWith ( '.gjs' ) || filename . endsWith ( '.gts' ) ;
8585 const elementStack = [ ] ;
8686
87+ // local name → original name ('Input' | 'Textarea')
88+ // Only populated in GJS/GTS files via ImportDeclaration
89+ const importedFormComponents = new Map ( ) ;
90+
8791 function hasValidLabelParent ( ) {
8892 for ( let i = elementStack . length - 1 ; i >= 0 ; i -- ) {
8993 const entry = elementStack [ i ] ;
@@ -104,15 +108,38 @@ module.exports = {
104108 }
105109
106110 return {
107- GlimmerElementNode ( node ) {
108- elementStack . push ( { tag : node . tag , node } ) ;
109-
110- if ( isStrictMode && ( node . tag === 'Input' || node . tag === 'Textarea' ) ) {
111+ ImportDeclaration ( node ) {
112+ if ( ! isStrictMode ) {
111113 return ;
112114 }
115+ if ( node . source . value === '@ember/component' ) {
116+ for ( const specifier of node . specifiers ) {
117+ if ( specifier . type === 'ImportSpecifier' ) {
118+ const original = specifier . imported . name ;
119+ if ( original === 'Input' || original === 'Textarea' ) {
120+ importedFormComponents . set ( specifier . local . name , original ) ;
121+ }
122+ }
123+ }
124+ }
125+ } ,
113126
114- const tagName = node . tag ?. toLowerCase ( ) ;
115- if ( tagName !== 'input' && tagName !== 'textarea' && tagName !== 'select' ) {
127+ GlimmerElementNode ( node ) {
128+ elementStack . push ( { tag : node . tag , node } ) ;
129+
130+ const tag = node . tag ;
131+ // Is this tag one we should check?
132+ // - Native <input>/<textarea>/<select> always.
133+ // - <Input>/<Textarea> built-ins:
134+ // - In strict mode (.gjs/.gts): only if the tag resolves to a tracked
135+ // import from '@ember/component' (supports renames).
136+ // - In HBS: match by bare tag name.
137+ const isNativeFormElement = tag === 'input' || tag === 'textarea' || tag === 'select' ;
138+ const isBuiltinFormComponent = isStrictMode
139+ ? importedFormComponents . has ( tag )
140+ : tag === 'Input' || tag === 'Textarea' ;
141+
142+ if ( ! isNativeFormElement && ! isBuiltinFormComponent ) {
116143 return ;
117144 }
118145
@@ -164,6 +191,13 @@ module.exports = {
164191 } ,
165192
166193 GlimmerMustacheStatement ( node ) {
194+ // Classic {{input}}/{{textarea}} curly helpers only exist in HBS.
195+ // In GJS/GTS, these identifiers are user-imported JS bindings with
196+ // no relation to the classic helpers, so skip.
197+ if ( isStrictMode ) {
198+ return ;
199+ }
200+
167201 const name = node . path ?. original ;
168202 if ( name !== 'input' && name !== 'textarea' ) {
169203 return ;
0 commit comments