11import type { CMKConfig , Resolver } from '@css-modules-kit/core' ;
2- import { isComponentFileName } from '@css-modules-kit/core' ;
2+ import { isComponentFileName , isCSSModuleFile } from '@css-modules-kit/core' ;
33import type { Language } from '@volar/language-core' ;
44import ts from 'typescript' ;
55import { isCSSModuleScript } from '../../language-plugin.js' ;
@@ -31,6 +31,7 @@ export function getCodeFixesAtPosition(
3131
3232 if ( config . namedExports && ! config . prioritizeNamedImports ) {
3333 convertDefaultImportsToNamespaceImports ( prior , fileName , resolver ) ;
34+ excludeNamedImports ( prior , fileName , resolver ) ;
3435 }
3536
3637 if ( isComponentFileName ( fileName ) ) {
@@ -47,10 +48,29 @@ export function getCodeFixesAtPosition(
4748 }
4849 }
4950
50- return prior ;
51+ return prior . filter ( ( codeFix ) => codeFix . changes . length > 0 ) ;
5152 } ;
5253}
5354
55+ /**
56+ * Exclude code fixes that add named imports (e.g. `import { foo } from './a.module.css'`)
57+ */
58+ function excludeNamedImports ( codeFixes : ts . CodeFixAction [ ] , fileName : string , resolver : Resolver ) : void {
59+ for ( const codeFix of codeFixes ) {
60+ if ( codeFix . fixName !== 'import' ) continue ;
61+ const match = codeFix . description . match ( / ^ A d d i m p o r t f r o m " ( .* ) " $ / u) ;
62+ if ( ! match ) continue ;
63+ const specifier = match [ 1 ] ! ;
64+ const resolved = resolver ( specifier , { request : fileName } ) ;
65+ if ( ! resolved || ! isCSSModuleFile ( resolved ) ) continue ;
66+
67+ for ( const change of codeFix . changes ) {
68+ change . textChanges = change . textChanges . filter ( ( textChange ) => ! textChange . newText . startsWith ( `import {` ) ) ;
69+ }
70+ codeFix . changes = codeFix . changes . filter ( ( change ) => change . textChanges . length > 0 ) ;
71+ }
72+ }
73+
5474interface TokenConsumer {
5575 /** The token name (e.g. `foo` in `styles.foo`) */
5676 tokenName : string ;
0 commit comments