@@ -81,13 +81,44 @@ export class IconsCollectionController {
8181 . filter ( Boolean ) ;
8282 }
8383
84+ private static readonly ICON_ALIASES : Record < string , string > = {
85+ nodedotjs : 'nodejs' ,
86+ node : 'nodejs' ,
87+ vue : 'vuedotjs' ,
88+ ember : 'emberdotjs' ,
89+ emberjs : 'emberdotjs' ,
90+ three : 'threedotjs' ,
91+ threejs : 'threedotjs' ,
92+ chart : 'chartdotjs' ,
93+ chartjs : 'chartdotjs' ,
94+ fly : 'flydotio' ,
95+ flyio : 'flydotio' ,
96+ devto : 'devdotto' ,
97+ gitignoredotio : 'gitignoredotio' ,
98+ gitignore : 'gitignoredotio' ,
99+ js : 'javascript' ,
100+ ts : 'typescript' ,
101+ py : 'python' ,
102+ cpp : 'cplusplus' ,
103+ 'c++' : 'cplusplus' ,
104+ cs : 'csharp' ,
105+ postgres : 'postgresql' ,
106+ golang : 'go' ,
107+ } ;
108+
109+ public static resolveIconName ( iconName : string ) : string {
110+ const normalized = iconName . toLowerCase ( ) ;
111+ return IconsCollectionController . ICON_ALIASES [ normalized ] || normalized ;
112+ }
113+
84114 private static resolveIconPath ( iconName : string ) : string | null {
85- if ( ! IconsCollectionController . ICON_NAME_REGEX . test ( iconName ) ) {
115+ const targetName = IconsCollectionController . resolveIconName ( iconName ) ;
116+ if ( ! IconsCollectionController . ICON_NAME_REGEX . test ( targetName ) ) {
86117 return null ;
87118 }
88119
89120 const resolvedIconsDir = path . resolve ( IconsCollectionController . iconsDir ) ;
90- const iconPath = path . resolve ( IconsCollectionController . iconsDir , `${ iconName } .svg` ) ;
121+ const iconPath = path . resolve ( IconsCollectionController . iconsDir , `${ targetName } .svg` ) ;
91122
92123 if ( ! iconPath . startsWith ( resolvedIconsDir + path . sep ) && iconPath !== resolvedIconsDir ) {
93124 return null ;
@@ -97,16 +128,20 @@ export class IconsCollectionController {
97128 }
98129
99130 private static async readBaseIconContent ( iconName : string ) : Promise < string > {
100- const iconPath = IconsCollectionController . resolveIconPath ( iconName ) ;
131+ const targetName = IconsCollectionController . resolveIconName ( iconName ) ;
132+ const iconPath = IconsCollectionController . resolveIconPath ( targetName ) ;
101133 if ( ! iconPath ) {
102134 throw new Error ( 'INVALID_ICON_NAME' ) ;
103135 }
104136
105- let pending = IconsCollectionController . pendingLoads . get ( iconName ) ;
137+ let pending = IconsCollectionController . pendingLoads . get ( targetName ) ;
106138 if ( ! pending ) {
107- pending = fs . readFile ( iconPath , 'utf-8' ) ;
108- IconsCollectionController . pendingLoads . set ( iconName , pending ) ;
109- pending . finally ( ( ) => IconsCollectionController . pendingLoads . delete ( iconName ) ) ;
139+ pending = fs . readFile ( iconPath , 'utf-8' ) . then ( ( content ) => {
140+ // Strip embedded individual icon popup styles so collection rendering is clean and instant
141+ return content . replace ( / < s t y l e [ \s \S ] * ?< \/ s t y l e > / gi, '' ) ;
142+ } ) ;
143+ IconsCollectionController . pendingLoads . set ( targetName , pending ) ;
144+ pending . finally ( ( ) => IconsCollectionController . pendingLoads . delete ( targetName ) ) ;
110145 }
111146
112147 return pending ;
@@ -264,12 +299,14 @@ export class IconsCollectionController {
264299 const preset = IconsCollectionController . ICON_SIZE_PRESETS [ size ] ;
265300 const totalColumns = Math . min ( columns , iconNames . length ) ;
266301 const totalRows = Math . ceil ( iconNames . length / totalColumns ) ;
302+ const waveYOffset = effect === 'wave' ? 10 : 0 ;
267303 const width =
268304 preset . padding * 2 +
269305 totalColumns * preset . cell +
270306 ( totalColumns - 1 ) * preset . gap ;
271307 const height =
272308 preset . padding * 2 +
309+ waveYOffset +
273310 totalRows * preset . cell +
274311 ( totalRows - 1 ) * preset . gap ;
275312
@@ -300,6 +337,7 @@ export class IconsCollectionController {
300337 ( preset . cell - preset . icon ) / 2 ;
301338 const y =
302339 preset . padding +
340+ waveYOffset +
303341 row * ( preset . cell + preset . gap ) +
304342 ( preset . cell - preset . icon ) / 2 ;
305343 const delay = column * 0.12 + row * 0.08 ;
@@ -330,7 +368,7 @@ export class IconsCollectionController {
330368 } ) ,
331369 ) ;
332370
333- return `<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="${ width } " height="${ height } " viewBox="0 0 ${ width } ${ height } " role="img" aria-label="Icon collection">
371+ return `<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="${ width } " height="${ height } " viewBox="0 0 ${ width } ${ height } " overflow="visible" role="img" aria-label="Icon collection">
334372 <title>Icon collection</title>
335373 ${ defs . length > 0 ? `<defs>
336374 ${ defs . join ( '\n ' ) }
@@ -408,12 +446,13 @@ export class IconsCollectionController {
408446
409447 const resolvedIconNames = (
410448 await Promise . all (
411- normalizedIconNames . map ( async ( iconName ) => {
449+ normalizedIconNames . map ( async ( rawName ) => {
450+ const targetName = IconsCollectionController . resolveIconName ( rawName ) ;
412451 try {
413452 await fs . access (
414- path . resolve ( IconsCollectionController . iconsDir , `${ iconName } .svg` ) ,
453+ path . resolve ( IconsCollectionController . iconsDir , `${ targetName } .svg` ) ,
415454 ) ;
416- return iconName ;
455+ return targetName ;
417456 } catch {
418457 return null ;
419458 }
0 commit comments