@@ -20,6 +20,7 @@ import type {
2020 SourceIndex ,
2121} from '@/lib/analyze-data'
2222import { splitIdent } from '@/lib/utils'
23+ import clsx from 'clsx'
2324
2425interface ImportChainProps {
2526 startFileId : number
@@ -53,52 +54,61 @@ interface DependentInfo {
5354 depth : number
5455}
5556
56- function getPathDifference ( currentPath : string , previousPath : string | null ) {
57- if ( ! previousPath ) {
58- return { common : '' , different : currentPath }
59- }
57+ type PathPart = {
58+ segment : string
59+ isCommon : boolean
60+ isLastCommon : boolean
61+ isPackageName : boolean
62+ isInfrastructure : boolean
63+ }
64+
65+ function spitPathSegments ( path : string ) : string [ ] {
66+ return Array . from ( path . matchAll ( / ( .+ ?(?: \/ | $ ) ) / g) ) . map ( ( [ i ] ) => i )
67+ }
6068
61- const currentSegments = currentPath . split ( '/' )
62- const previousSegments = previousPath . split ( '/' )
69+ function getPathParts (
70+ currentPath : string ,
71+ previousPath : string | null
72+ ) : PathPart [ ] {
73+ const currentSegments = spitPathSegments ( currentPath )
6374
6475 let commonCount = 0
65- const minLength = Math . min ( currentSegments . length , previousSegments . length )
76+ if ( previousPath ) {
77+ const previousSegments = spitPathSegments ( previousPath )
6678
67- for ( let i = 0 ; i < minLength ; i ++ ) {
68- if ( currentSegments [ i ] === previousSegments [ i ] ) {
69- commonCount ++
70- } else {
71- break
79+ const minLength = Math . min ( currentSegments . length , previousSegments . length )
80+
81+ for ( let i = 0 ; i < minLength ; i ++ ) {
82+ if ( currentSegments [ i ] === previousSegments [ i ] ) {
83+ commonCount ++
84+ } else {
85+ break
86+ }
7287 }
7388 }
7489
75- const commonSegments = currentSegments . slice ( 0 , commonCount )
76- const differentSegments = currentSegments . slice ( commonCount )
77-
78- const common =
79- commonSegments . length === 0
80- ? ''
81- : differentSegments . length === 0
82- ? ` ${ commonSegments . join ( '/' ) } `
83- : ` ${ commonSegments . join ( '/' ) } /`
84- return {
85- common ,
86- different : differentSegments . join ( '/' ) ,
90+ let infrastructureCount = 0
91+ let packageNameCount = 0
92+ let nodeModulesIndex = currentSegments . lastIndexOf ( 'node_modules/' )
93+ if ( nodeModulesIndex === - 1 ) {
94+ nodeModulesIndex = currentSegments . length
95+ } else {
96+ infrastructureCount = nodeModulesIndex + 1
97+ if ( currentSegments [ nodeModulesIndex + 1 ] ?. startsWith ( '@' ) ) {
98+ packageNameCount = 2
99+ } else {
100+ packageNameCount = 1
101+ }
87102 }
88- }
89103
90- const insertLineBreaks = ( path : string ) => {
91- const segments = path . split ( '/' )
92- return segments . map ( ( segment , i ) => (
93- < span
94- key = { `${ segment } -${ i } ` }
95- className = { segment . length > 20 ? 'break-all' : '' }
96- >
97- { segment }
98- { i < segments . length - 1 && '/' }
99- < wbr />
100- </ span >
101- ) )
104+ return currentSegments . map ( ( segment , i ) => ( {
105+ segment,
106+ isCommon : i < commonCount ,
107+ isLastCommon : i === commonCount - 1 ,
108+ isInfrastructure : i < infrastructureCount ,
109+ isPackageName :
110+ i >= infrastructureCount && i < infrastructureCount + packageNameCount ,
111+ } ) )
102112}
103113
104114function getTitle ( level : ChainLevel ) {
@@ -330,10 +340,7 @@ export function ImportChain({
330340 < div className = "space-y-0" >
331341 { chain . map ( ( level , index ) => {
332342 const previousPath = index > 0 ? chain [ index - 1 ] . path : null
333- const { common, different } = getPathDifference (
334- level . path ,
335- previousPath
336- )
343+ const parts = getPathParts ( level . path , previousPath )
337344
338345 const flags =
339346 level . sourceIndex !== undefined
@@ -402,21 +409,35 @@ export function ImportChain({
402409 className = "font-mono text-xs text-foreground text-center block break-words"
403410 title = { getTitle ( level ) }
404411 >
405- { index === 0 ? (
406- < span className = "font-normal" >
407- { insertLineBreaks ( level . path ) }
408- </ span >
409- ) : (
410- < >
411- { common && (
412- < span className = "font-normal text-muted-foreground/60" >
413- { insertLineBreaks ( common ) }
414- </ span >
415- ) }
416- < span className = "font-bold" >
417- { insertLineBreaks ( different ) }
412+ { parts . map (
413+ (
414+ {
415+ segment,
416+ isCommon,
417+ isLastCommon,
418+ isInfrastructure,
419+ isPackageName,
420+ } ,
421+ i
422+ ) => (
423+ < span
424+ key = { i }
425+ className = { clsx (
426+ segment . length > 20 && 'break-all' ,
427+ isCommon &&
428+ ! isLastCommon &&
429+ ! isPackageName &&
430+ ! isInfrastructure &&
431+ 'text-muted-foreground/80' ,
432+ ! isCommon && ! isInfrastructure && 'font-bold' ,
433+ isInfrastructure && 'text-muted-foreground/50' ,
434+ isPackageName && 'text-orange-500'
435+ ) }
436+ >
437+ { segment }
438+ < wbr />
418439 </ span >
419- </ >
440+ )
420441 ) }
421442 </ span >
422443 </ div >
0 commit comments