@@ -4,6 +4,7 @@ import {API, FileInfo} from 'jscodeshift';
44import { changes as changesJSON } from './changes' ;
55import { functionMap } from './transforms' ;
66import { getComponents } from '../getComponents' ;
7+ import { iconMap } from '../iconMap' ;
78import * as t from '@babel/types' ;
89import { transformStyleProps } from './styleProps' ;
910import traverse , { Binding , NodePath } from '@babel/traverse' ;
@@ -39,6 +40,7 @@ export default function transformer(file: FileInfo, api: API, options: Options)
3940 let importedComponents = new Map < string , t . ImportSpecifier | t . ImportNamespaceSpecifier > ( ) ;
4041 let elements : [ string , NodePath < t . JSXElement > ] [ ] = [ ] ;
4142 let lastImportPath : NodePath < t . ImportDeclaration > | null = null ;
43+ let iconImports : Map < string , { path : NodePath < t . ImportDeclaration > , newName : string | null } > = new Map ( ) ;
4244 const leadingComments = root . find ( j . Program ) . get ( 'body' , 0 ) . node . leadingComments ;
4345 traverse ( root . paths ( ) [ 0 ] . node , {
4446 ImportDeclaration ( path ) {
@@ -90,6 +92,22 @@ export default function transformer(file: FileInfo, api: API, options: Options)
9092 }
9193 }
9294 }
95+ } else if ( path . node . source . value . startsWith ( '@spectrum-icons/workflow/' ) ) {
96+ let importSource = path . node . source . value ;
97+ let iconName = importSource . split ( '/' ) . pop ( ) ;
98+ if ( ! iconName ) { return ; }
99+
100+ let specifier = path . node . specifiers [ 0 ] ;
101+ if ( ! specifier || ! t . isImportDefaultSpecifier ( specifier ) ) { return ; }
102+
103+ let localName = specifier . local . name ;
104+
105+ if ( iconMap . has ( iconName ) ) {
106+ let newIconName = iconMap . get ( iconName ) ! ;
107+ iconImports . set ( localName , { path, newName : newIconName } ) ;
108+ } else {
109+ iconImports . set ( localName , { path, newName : null } ) ;
110+ }
93111 }
94112 } ,
95113 Import ( path ) {
@@ -109,6 +127,41 @@ export default function transformer(file: FileInfo, api: API, options: Options)
109127
110128 // TODO: implement this. could be a bit challenging. punting for now.
111129 addComment ( call . node , ' TODO(S2-upgrade): check this dynamic import' ) ;
130+ } ,
131+ JSXOpeningElement ( path ) {
132+ let name = path . node . name ;
133+ if ( t . isJSXIdentifier ( name ) && iconImports . has ( name . name ) ) {
134+ let iconInfo = iconImports . get ( name . name ) ! ;
135+ if ( iconInfo . newName === null ) {
136+ addComment ( path . node , ` TODO(S2-upgrade): A Spectrum 2 equivalent to '${ name . name } ' was not found. Please update this icon manually.` ) ;
137+ }
138+ }
139+ }
140+ } ) ;
141+
142+ iconImports . forEach ( ( iconInfo , localName ) => {
143+ let { path, newName} = iconInfo ;
144+ if ( newName ) {
145+ let newImportSource = `@react-spectrum/s2/icons/${ newName } ` ;
146+
147+ // Check if we can update local name
148+ let newLocalName = localName ;
149+ if ( localName === path . node . source . value . split ( '/' ) . pop ( ) && localName !== newName ) {
150+ let binding = path . scope . getBinding ( localName ) ;
151+ if ( binding && ! path . scope . hasBinding ( newName ) ) {
152+ newLocalName = newName ;
153+ // Rename all references
154+ binding . referencePaths . forEach ( refPath => {
155+ if ( t . isJSXIdentifier ( refPath . node ) ) {
156+ refPath . node . name = newName ;
157+ }
158+ } ) ;
159+ }
160+ }
161+
162+ // Update the import
163+ path . node . source = t . stringLiteral ( newImportSource ) ;
164+ path . node . specifiers = [ t . importDefaultSpecifier ( t . identifier ( newLocalName ) ) ] ;
112165 }
113166 } ) ;
114167
0 commit comments