Skip to content

Commit c61a83b

Browse files
committed
feat: improve module id coloring
1 parent 0c5bdaa commit c61a83b

File tree

7 files changed

+251
-134
lines changed

7 files changed

+251
-134
lines changed
Lines changed: 4 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,19 @@
11
<script setup lang="ts">
22
import { computed } from 'vue'
33
import { isDark } from '../../composables/dark'
4+
import { getFileTypeFromModuleId } from '../../utils/icon'
45
56
const props = defineProps<{
67
filename: string
78
}>()
89
9-
const map = {
10-
angular: 'i-catppuccin-angular',
11-
vue: 'i-catppuccin-vue',
12-
js: 'i-catppuccin-javascript',
13-
mjs: 'i-catppuccin-javascript',
14-
cjs: 'i-catppuccin-javascript',
15-
ts: 'i-catppuccin-typescript',
16-
mts: 'i-catppuccin-typescript',
17-
cts: 'i-catppuccin-typescript',
18-
md: 'i-catppuccin-markdown',
19-
markdown: 'i-catppuccin-markdown',
20-
mdx: 'i-catppuccin-mdx',
21-
jsx: 'i-catppuccin-javascript-react',
22-
tsx: 'i-catppuccin-typescript-react',
23-
svelte: 'i-catppuccin-svelte',
24-
html: 'i-catppuccin-html',
25-
css: 'i-catppuccin-css',
26-
scss: 'i-catppuccin-css',
27-
less: 'i-catppuccin-less',
28-
json: 'i-catppuccin-json',
29-
yaml: 'i-catppuccin-yaml',
30-
toml: 'i-catppuccin-toml',
31-
svg: 'i-catppuccin-svg',
32-
} as Record<string, string>
33-
34-
const icon = computed(() => {
35-
let file = props.filename
36-
file = file
37-
.replace(/(\?|&)v=[^&]*/, '$1')
38-
.replace(/\?$/, '')
39-
40-
if (file.match(/[\\/]node_modules[\\/]/))
41-
return 'i-catppuccin-folder-node-open'
42-
43-
let ext = (file.split('.').pop() || '').toLowerCase()
44-
let icon = map[ext]
45-
if (icon)
46-
return icon
47-
48-
ext = ext.split('?')[0]
49-
icon = map[ext]
50-
if (icon)
51-
return icon
52-
53-
return 'i-catppuccin-file'
54-
})
10+
const info = computed(() => getFileTypeFromModuleId(props.filename))
5511
</script>
5612

5713
<template>
5814
<div
5915
flex-none
60-
:class="[icon, isDark ? '' : 'brightness-60 hue-rotate-180 invert-100 saturate-200']"
16+
:title="info.description || info.name"
17+
:class="[info.icon, isDark ? '' : 'brightness-60 hue-rotate-180 invert-100 saturate-200']"
6118
/>
6219
</template>

packages/devtools/src/app/components/display/FilepathItem.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script setup lang="ts">
22
import { computed } from 'vue'
3-
import { parseReadablePath } from '~/utils/filepath'
3+
import { parseReadablePath } from '../../utils/filepath'
44
55
const props = defineProps<{
66
filepath?: string
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import { defineComponent, h } from 'vue'
2+
import { getPluginColor } from '../../utils/color'
3+
4+
export default defineComponent({
5+
name: 'HighlightedPath',
6+
props: {
7+
path: {
8+
type: String,
9+
required: true,
10+
},
11+
},
12+
setup(props) {
13+
return () => {
14+
const parts = props.path.split(/([/?&:=])/g)
15+
let type: 'start' | 'path' | 'query' = 'start'
16+
17+
const classes: string[][] = parts.map(() => [])
18+
const styles: string[][] = parts.map(() => [])
19+
const nodes = parts.map((part) => {
20+
return h('span', { class: '' }, part)
21+
})
22+
23+
const removeIndexes = new Set<number>()
24+
25+
parts.forEach((part, index) => {
26+
if (part === '?')
27+
type = 'query'
28+
29+
if (type === 'start') {
30+
if (part.match(/^\.+$/)) {
31+
classes[index].push('op50')
32+
}
33+
else if (part === '/') {
34+
classes[index].push('op50')
35+
}
36+
else if (part !== '/') {
37+
type = 'path'
38+
}
39+
}
40+
41+
if (type === 'path') {
42+
if (part === '/') {
43+
classes[index].push('op50')
44+
}
45+
else if (part === 'node_modules' || part === 'dist' || part === 'lib' || part.match(/^\.\w/)) {
46+
classes[index].push('op60')
47+
}
48+
49+
if (part === '.pnpm') {
50+
classes[index]?.push('op50')
51+
if (nodes[index])
52+
nodes[index].children = '…'
53+
removeIndexes.add(index + 1)
54+
removeIndexes.add(index + 2)
55+
if (nodes[index + 4]?.children === 'node_modules') {
56+
removeIndexes.add(index + 3)
57+
removeIndexes.add(index + 4)
58+
}
59+
}
60+
if (part === ':') {
61+
if (nodes[index - 1]) {
62+
styles[index - 1].push(`color: ${getPluginColor(parts[index - 1])}`)
63+
}
64+
classes[index].push('op50')
65+
}
66+
if (parts[index - 2] === 'node_modules' && !part.startsWith('.')) {
67+
const color = `color: ${getPluginColor(parts[index])}`
68+
styles[index].push(color)
69+
if (part.startsWith('@')) {
70+
styles[index + 1].push(color)
71+
styles[index + 2].push(color)
72+
}
73+
}
74+
}
75+
76+
if (type === 'query') {
77+
if (part === '?') {
78+
classes[index].push('text-red-5 dark:text-red-4')
79+
}
80+
else if (part === '&') {
81+
classes[index].push('text-orange-5 dark:text-orange-4')
82+
}
83+
if (part === '=') {
84+
classes[index].push('text-orange-9 dark:text-orange-2 op50')
85+
}
86+
else if (parts[index + 1] === '=') {
87+
classes[index].push('text-amber-9 dark:text-amber-2')
88+
}
89+
else {
90+
classes[index].push('text-orange-9 dark:text-orange-2')
91+
}
92+
}
93+
})
94+
95+
nodes.forEach((node, index) => {
96+
if (node.props) {
97+
node.props.class = classes[index].join(' ')
98+
node.props.style = styles[index].join(';')
99+
}
100+
})
101+
102+
Array.from(removeIndexes)
103+
.sort((a, b) => b - a)
104+
.forEach((index) => {
105+
nodes.splice(index, 1)
106+
})
107+
108+
return nodes
109+
}
110+
},
111+
})

packages/devtools/src/app/components/display/ModuleId.vue

Lines changed: 2 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
<script setup lang="ts">
22
import { vTooltip } from 'floating-vue'
33
import { relative } from 'pathe'
4-
import { computed, defineComponent, h } from 'vue'
5-
import { getPluginColor } from '../../utils/color'
4+
import { computed } from 'vue'
65
76
const props = withDefaults(
87
defineProps<{
@@ -33,89 +32,6 @@ const relativePath = computed(() => {
3332
return id
3433
})
3534
36-
const HighlightedPath = defineComponent({
37-
render() {
38-
const parts = relativePath.value.split(/([/?&:])/g)
39-
let type: 'start' | 'path' | 'query' = 'start'
40-
41-
const classes: string[][] = parts.map(() => [])
42-
const nodes = parts.map((part) => {
43-
return h('span', { class: '' }, part)
44-
})
45-
46-
const removeIndexes = new Set<number>()
47-
48-
parts.forEach((part, index) => {
49-
const _class = classes[index]
50-
if (part === '?')
51-
type = 'query'
52-
53-
if (type === 'start') {
54-
if (part.match(/^\.+$/)) {
55-
_class.push('op50')
56-
}
57-
else if (part === '/') {
58-
_class.push('op50')
59-
}
60-
else if (part !== '/') {
61-
type = 'path'
62-
}
63-
}
64-
65-
if (type === 'path') {
66-
if (part === '/' || part === 'node_modules' || part.match(/^\.\w/)) {
67-
_class.push('op75')
68-
}
69-
if (part === '.pnpm') {
70-
classes[index]?.push('op50')
71-
if (nodes[index])
72-
nodes[index].children = ''
73-
removeIndexes.add(index + 1)
74-
removeIndexes.add(index + 2)
75-
if (nodes[index + 4]?.children === 'node_modules') {
76-
removeIndexes.add(index + 3)
77-
removeIndexes.add(index + 4)
78-
}
79-
}
80-
if (part === ':') {
81-
if (nodes[index - 1]) {
82-
nodes[index - 1].props ||= {}
83-
nodes[index - 1].props!.style ||= {}
84-
nodes[index - 1].props!.style.color = getPluginColor(parts[index - 1])
85-
}
86-
_class.push('op50')
87-
}
88-
if (parts[index - 2] === 'node_modules' && !part.startsWith('.')) {
89-
_class.push('text-purple-5 dark:text-purple-4')
90-
}
91-
}
92-
93-
if (type === 'query') {
94-
if (part === '?' || part === '&') {
95-
_class.push('text-orange-5 dark:text-orange-4')
96-
}
97-
else {
98-
_class.push('text-orange-9 dark:text-orange-2')
99-
}
100-
}
101-
})
102-
103-
nodes.forEach((node, index) => {
104-
if (node.props)
105-
node.props.class = classes[index].join(' ')
106-
})
107-
108-
Array.from(removeIndexes)
109-
.sort((a, b) => b - a)
110-
.forEach((index) => {
111-
nodes.splice(index, 1)
112-
classes.splice(index, 1)
113-
})
114-
115-
return nodes
116-
},
117-
})
118-
11935
const gridStyles = computed(() => {
12036
if (!props.module)
12137
return ''
@@ -157,7 +73,7 @@ const containerClass = computed(() => {
15773
>
15874
<DisplayFileIcon v-if="icon" :filename="id" mr1.5 />
15975
<span :class="{ 'overflow-hidden': module, 'text-truncate': module }">
160-
<HighlightedPath />
76+
<DisplayHighlightedPath :path="relativePath" />
16177
</span>
16278
<slot />
16379

packages/devtools/src/app/utils/color.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ const predefinedColorMap = {
4848
} as Record<string, number>
4949

5050
export function getPluginColor(name: string, opacity = 1): string {
51+
name = name.replace(/[^a-z]+/gi, '').toLowerCase()
5152
if (predefinedColorMap[name]) {
5253
const color = predefinedColorMap[name]
5354
if (typeof color === 'number') {

0 commit comments

Comments
 (0)