forked from
npmx.dev/npmx.dev
[READ-ONLY]
a fast, modern browser for the npm registry
1/**
2 * Get icon class for a file based on its name/extension.
3 * Uses vscode-icons and lucide icons.
4 *
5 * Based on this file, a sprite file (<ORIGIN_URL>/file-tree-sprite.svg) is generated on postinstall
6 * @see /scripts/generate-file-tree-sprite.ts
7 */
8
9// Extension to icon mapping
10// @unocss-include
11export const EXTENSION_ICONS: Record<string, string> = {
12 // JavaScript/TypeScript
13 'js': 'vscode-icons-file-type-js-official',
14 'mjs': 'vscode-icons-file-type-js-official',
15 'cjs': 'vscode-icons-file-type-js-official',
16 'ts': 'vscode-icons-file-type-typescript-official',
17 'mts': 'vscode-icons-file-type-typescript-official',
18 'cts': 'vscode-icons-file-type-typescript-official',
19 'jsx': 'vscode-icons-file-type-reactjs',
20 'tsx': 'vscode-icons-file-type-reactts',
21
22 // Web
23 'html': 'vscode-icons-file-type-html',
24 'htm': 'vscode-icons-file-type-html',
25 'css': 'vscode-icons-file-type-css',
26 'scss': 'vscode-icons-file-type-scss',
27 'sass': 'vscode-icons-file-type-sass',
28 'less': 'vscode-icons-file-type-less',
29 'styl': 'vscode-icons-file-type-stylus',
30 'vue': 'vscode-icons-file-type-vue',
31 'svelte': 'vscode-icons-file-type-svelte',
32 'astro': 'vscode-icons-file-type-astro',
33 'gjs': 'vscode-icons-file-type-glimmer',
34 'gts': 'vscode-icons-file-type-glimmer',
35
36 // Config/Data
37 'json': 'vscode-icons-file-type-json',
38 'jsonc': 'vscode-icons-file-type-json',
39 'json5': 'vscode-icons-file-type-json5',
40 'yaml': 'vscode-icons-file-type-yaml',
41 'yml': 'vscode-icons-file-type-yaml',
42 'toml': 'vscode-icons-file-type-toml',
43 'xml': 'vscode-icons-file-type-xml',
44 'svg': 'vscode-icons-file-type-svg',
45 'graphql': 'vscode-icons-file-type-graphql',
46 'gql': 'vscode-icons-file-type-graphql',
47 'prisma': 'vscode-icons-file-type-prisma',
48
49 // Documentation
50 'md': 'vscode-icons-file-type-markdown',
51 'mdx': 'vscode-icons-file-type-mdx',
52 'txt': 'vscode-icons-file-type-text',
53 'rst': 'vscode-icons-file-type-text',
54 'pdf': 'vscode-icons-file-type-pdf2',
55
56 // Shell/Scripts
57 'sh': 'vscode-icons-file-type-shell',
58 'bash': 'vscode-icons-file-type-shell',
59 'zsh': 'vscode-icons-file-type-shell',
60 'fish': 'vscode-icons-file-type-shell',
61 'ps1': 'vscode-icons-file-type-powershell',
62 'bat': 'vscode-icons-file-type-bat',
63 'cmd': 'vscode-icons-file-type-bat',
64
65 // Programming languages
66 'py': 'vscode-icons-file-type-python',
67 'pyi': 'vscode-icons-file-type-python',
68 'rb': 'vscode-icons-file-type-ruby',
69 'go': 'vscode-icons-file-type-go',
70 'rs': 'vscode-icons-file-type-rust',
71 'java': 'vscode-icons-file-type-java',
72 'kt': 'vscode-icons-file-type-kotlin',
73 'swift': 'vscode-icons-file-type-swift',
74 'c': 'vscode-icons-file-type-c',
75 'cpp': 'vscode-icons-file-type-cpp',
76 'h': 'vscode-icons-file-type-cheader',
77 'hpp': 'vscode-icons-file-type-cppheader',
78 'cs': 'vscode-icons-file-type-csharp',
79 'php': 'vscode-icons-file-type-php',
80 'lua': 'vscode-icons-file-type-lua',
81 'luau': 'vscode-icons-file-type-luau',
82 'r': 'vscode-icons-file-type-r',
83 'sql': 'vscode-icons-file-type-sql',
84 'pl': 'vscode-icons-file-type-perl',
85 'ex': 'vscode-icons-file-type-elixir',
86 'exs': 'vscode-icons-file-type-elixir',
87 'erl': 'vscode-icons-file-type-erlang',
88 'hs': 'vscode-icons-file-type-haskell',
89 'clj': 'vscode-icons-file-type-clojure',
90 'scala': 'vscode-icons-file-type-scala',
91 'zig': 'vscode-icons-file-type-zig',
92 'nim': 'vscode-icons-file-type-nim',
93 'v': 'vscode-icons-file-type-vlang',
94 'wasm': 'vscode-icons-file-type-wasm',
95
96 // Images
97 'png': 'vscode-icons-file-type-image',
98 'jpg': 'vscode-icons-file-type-image',
99 'jpeg': 'vscode-icons-file-type-image',
100 'gif': 'vscode-icons-file-type-image',
101 'webp': 'vscode-icons-file-type-image',
102 'ico': 'vscode-icons-file-type-image',
103 'bmp': 'vscode-icons-file-type-image',
104
105 // Fonts
106 'woff': 'vscode-icons-file-type-font',
107 'woff2': 'vscode-icons-file-type-font',
108 'ttf': 'vscode-icons-file-type-font',
109 'otf': 'vscode-icons-file-type-font',
110 'eot': 'vscode-icons-file-type-font',
111
112 // Archives
113 'zip': 'vscode-icons-file-type-zip',
114 'tar': 'vscode-icons-file-type-zip',
115 'gz': 'vscode-icons-file-type-zip',
116 'tgz': 'vscode-icons-file-type-zip',
117 'bz2': 'vscode-icons-file-type-zip',
118 '7z': 'vscode-icons-file-type-zip',
119 'rar': 'vscode-icons-file-type-zip',
120
121 // Certificates/Keys
122 'pem': 'vscode-icons-file-type-cert',
123 'crt': 'vscode-icons-file-type-cert',
124 'key': 'vscode-icons-file-type-key',
125
126 // Diff/Patch
127 'diff': 'vscode-icons-file-type-diff',
128 'patch': 'vscode-icons-file-type-diff',
129
130 // Other
131 'log': 'vscode-icons-file-type-log',
132 'lock': 'vscode-icons-file-type-json',
133 'map': 'vscode-icons-file-type-map',
134 'wrl': 'vscode-icons-file-type-binary',
135 'bin': 'vscode-icons-file-type-binary',
136 'node': 'vscode-icons-file-type-node',
137}
138
139// Special filenames that have specific icons
140export const FILENAME_ICONS: Record<string, string> = {
141 // Package managers
142 'package.json': 'vscode-icons-file-type-npm',
143 'package-lock.json': 'vscode-icons-file-type-npm',
144 'pnpm-lock.yaml': 'vscode-icons-file-type-pnpm',
145 'pnpm-workspace.yaml': 'vscode-icons-file-type-pnpm',
146 'yarn.lock': 'vscode-icons-file-type-yarn',
147 '.yarnrc': 'vscode-icons-file-type-yarn',
148 '.yarnrc.yml': 'vscode-icons-file-type-yarn',
149 'bun.lockb': 'vscode-icons-file-type-bun',
150 'bunfig.toml': 'vscode-icons-file-type-bun',
151 'deno.json': 'vscode-icons-file-type-deno',
152 'deno.jsonc': 'vscode-icons-file-type-deno',
153
154 // TypeScript configs
155 'tsconfig.json': 'vscode-icons-file-type-tsconfig',
156 'tsconfig.base.json': 'vscode-icons-file-type-tsconfig',
157 'tsconfig.build.json': 'vscode-icons-file-type-tsconfig',
158 'tsconfig.node.json': 'vscode-icons-file-type-tsconfig',
159 'jsconfig.json': 'vscode-icons-file-type-jsconfig',
160
161 // Build tools
162 'vite.config.ts': 'vscode-icons-file-type-vite',
163 'vite.config.js': 'vscode-icons-file-type-vite',
164 'vite.config.mts': 'vscode-icons-file-type-vite',
165 'vite.config.mjs': 'vscode-icons-file-type-vite',
166 'webpack.config.js': 'vscode-icons-file-type-webpack',
167 'webpack.config.ts': 'vscode-icons-file-type-webpack',
168 'rollup.config.js': 'vscode-icons-file-type-rollup',
169 'rollup.config.ts': 'vscode-icons-file-type-rollup',
170 'rollup.config.mjs': 'vscode-icons-file-type-rollup',
171 'esbuild.config.js': 'vscode-icons-file-type-esbuild',
172 'turbo.json': 'vscode-icons-file-type-turbo',
173 'nx.json': 'vscode-icons-file-type-nx',
174
175 // Framework configs
176 'nuxt.config.ts': 'vscode-icons-file-type-nuxt',
177 'nuxt.config.js': 'vscode-icons-file-type-nuxt',
178 'next.config.js': 'vscode-icons-file-type-next',
179 'next.config.mjs': 'vscode-icons-file-type-next',
180 'next.config.ts': 'vscode-icons-file-type-next',
181 'svelte.config.js': 'vscode-icons-file-type-svelte',
182 'astro.config.mjs': 'vscode-icons-file-type-astro',
183 'astro.config.ts': 'vscode-icons-file-type-astro',
184 'remix.config.js': 'vscode-icons-file-type-js-official',
185 'angular.json': 'vscode-icons-file-type-angular',
186 'nest-cli.json': 'vscode-icons-file-type-nestjs',
187
188 // Linting/Formatting
189 '.eslintrc': 'vscode-icons-file-type-eslint',
190 '.eslintrc.js': 'vscode-icons-file-type-eslint',
191 '.eslintrc.cjs': 'vscode-icons-file-type-eslint',
192 '.eslintrc.json': 'vscode-icons-file-type-eslint',
193 '.eslintrc.yml': 'vscode-icons-file-type-eslint',
194 'eslint.config.js': 'vscode-icons-file-type-eslint',
195 'eslint.config.mjs': 'vscode-icons-file-type-eslint',
196 'eslint.config.ts': 'vscode-icons-file-type-eslint',
197 '.prettierrc': 'vscode-icons-file-type-prettier',
198 '.prettierrc.js': 'vscode-icons-file-type-prettier',
199 '.prettierrc.json': 'vscode-icons-file-type-prettier',
200 'prettier.config.js': 'vscode-icons-file-type-prettier',
201 'prettier.config.mjs': 'vscode-icons-file-type-prettier',
202 '.prettierignore': 'vscode-icons-file-type-prettier',
203 'biome.json': 'vscode-icons-file-type-biome',
204 '.stylelintrc': 'vscode-icons-file-type-stylelint',
205 '.stylelintrc.json': 'vscode-icons-file-type-stylelint',
206
207 // Testing
208 'jest.config.js': 'vscode-icons-file-type-jest',
209 'jest.config.ts': 'vscode-icons-file-type-jest',
210 'vitest.config.ts': 'vscode-icons-file-type-vitest',
211 'vitest.config.js': 'vscode-icons-file-type-vitest',
212 'vitest.config.mts': 'vscode-icons-file-type-vitest',
213 'playwright.config.ts': 'vscode-icons-file-type-playwright',
214 'playwright.config.js': 'vscode-icons-file-type-playwright',
215 'cypress.config.ts': 'vscode-icons-file-type-cypress',
216 'cypress.config.js': 'vscode-icons-file-type-cypress',
217
218 // Git
219 '.gitignore': 'vscode-icons-file-type-git',
220 '.gitattributes': 'vscode-icons-file-type-git',
221 '.gitmodules': 'vscode-icons-file-type-git',
222 '.gitkeep': 'vscode-icons-file-type-git',
223
224 // CI/CD
225 '.travis.yml': 'vscode-icons-file-type-travis',
226 '.gitlab-ci.yml': 'vscode-icons-file-type-gitlab',
227 'Jenkinsfile': 'vscode-icons-file-type-jenkins',
228 'azure-pipelines.yml': 'vscode-icons-file-type-azurepipelines',
229 'cloudbuild.yaml': 'vscode-icons-file-type-yaml',
230 'vercel.json': 'vscode-icons-file-type-vercel',
231 'netlify.toml': 'vscode-icons-file-type-netlify',
232
233 // Docker
234 'Dockerfile': 'vscode-icons-file-type-docker',
235 'docker-compose.yml': 'vscode-icons-file-type-docker',
236 'docker-compose.yaml': 'vscode-icons-file-type-docker',
237 '.dockerignore': 'vscode-icons-file-type-docker',
238
239 // Environment
240 '.env': 'vscode-icons-file-type-dotenv',
241 '.env.local': 'vscode-icons-file-type-dotenv',
242 '.env.development': 'vscode-icons-file-type-dotenv',
243 '.env.production': 'vscode-icons-file-type-dotenv',
244 '.env.test': 'vscode-icons-file-type-dotenv',
245 '.env.example': 'vscode-icons-file-type-dotenv',
246
247 // Editor configs
248 '.editorconfig': 'vscode-icons-file-type-editorconfig',
249 '.vscode': 'vscode-icons-file-type-vscode',
250 'settings.json': 'vscode-icons-file-type-vscode',
251 'launch.json': 'vscode-icons-file-type-vscode',
252 'extensions.json': 'vscode-icons-file-type-vscode',
253
254 // Documentation
255 'README': 'vscode-icons-file-type-markdown',
256 'README.md': 'vscode-icons-file-type-markdown',
257 'readme.md': 'vscode-icons-file-type-markdown',
258 'README.markdown': 'vscode-icons-file-type-markdown',
259 'readme.markdown': 'vscode-icons-file-type-markdown',
260 'CHANGELOG': 'vscode-icons-file-type-markdown',
261 'CHANGELOG.md': 'vscode-icons-file-type-markdown',
262 'changelog.md': 'vscode-icons-file-type-markdown',
263 'CONTRIBUTING.md': 'vscode-icons-file-type-markdown',
264 'contributing.md': 'vscode-icons-file-type-markdown',
265 'CODE_OF_CONDUCT.md': 'vscode-icons-file-type-markdown',
266 'LICENSE': 'vscode-icons-file-type-license',
267 'LICENSE.md': 'vscode-icons-file-type-license',
268 'LICENSE.txt': 'vscode-icons-file-type-license',
269 'license': 'vscode-icons-file-type-license',
270 'license.md': 'vscode-icons-file-type-license',
271 'license.txt': 'vscode-icons-file-type-license',
272
273 // Node
274 '.npmrc': 'vscode-icons-file-type-npm',
275 '.npmignore': 'vscode-icons-file-type-npm',
276 '.nvmrc': 'vscode-icons-file-type-node',
277 '.node-version': 'vscode-icons-file-type-node',
278
279 // Misc
280 'Makefile': 'vscode-icons-file-type-makefile',
281 '.browserslistrc': 'vscode-icons-file-type-browserslist',
282 'browserslist': 'vscode-icons-file-type-browserslist',
283 '.babelrc': 'vscode-icons-file-type-babel',
284 'babel.config.js': 'vscode-icons-file-type-babel',
285 'tailwind.config.js': 'vscode-icons-file-type-tailwind',
286 'tailwind.config.ts': 'vscode-icons-file-type-tailwind',
287 'postcss.config.js': 'vscode-icons-file-type-postcss',
288 'postcss.config.cjs': 'vscode-icons-file-type-postcss',
289 'uno.config.ts': 'vscode-icons-file-type-unocss',
290 'unocss.config.ts': 'vscode-icons-file-type-unocss',
291}
292
293// Patterns for .d.ts and similar compound extensions
294export const COMPOUND_EXTENSIONS: Record<string, string> = {
295 '.d.ts': 'vscode-icons-file-type-typescriptdef',
296 '.d.mts': 'vscode-icons-file-type-typescriptdef',
297 '.d.cts': 'vscode-icons-file-type-typescriptdef',
298 '.test.ts': 'vscode-icons-file-type-testts',
299 '.test.js': 'vscode-icons-file-type-testjs',
300 '.spec.ts': 'vscode-icons-file-type-testts',
301 '.spec.js': 'vscode-icons-file-type-testjs',
302 '.test.tsx': 'vscode-icons-file-type-testts',
303 '.test.jsx': 'vscode-icons-file-type-testjs',
304 '.spec.tsx': 'vscode-icons-file-type-testts',
305 '.spec.jsx': 'vscode-icons-file-type-testjs',
306 '.stories.tsx': 'vscode-icons-file-type-storybook',
307 '.stories.ts': 'vscode-icons-file-type-storybook',
308 '.stories.jsx': 'vscode-icons-file-type-storybook',
309 '.stories.js': 'vscode-icons-file-type-storybook',
310 '.min.js': 'vscode-icons-file-type-js-official',
311 '.min.css': 'vscode-icons-file-type-css',
312}
313
314// Default icon for unknown files
315export const DEFAULT_ICON = 'vscode-icons-default-file'
316
317export const ADDITIONAL_ICONS = {
318 'folder': 'lucide-folder',
319 'folder-open': 'lucide-folder-open',
320}
321
322/**
323 * Get the icon class for a file based on its name
324 */
325export function getFileIcon(filename: string): string {
326 // Check exact filename match first
327 if (FILENAME_ICONS[filename]) {
328 return FILENAME_ICONS[filename]
329 }
330
331 // Check for compound extensions (e.g., .d.ts, .test.ts)
332 for (const [suffix, icon] of Object.entries(COMPOUND_EXTENSIONS)) {
333 if (filename.endsWith(suffix)) {
334 return icon
335 }
336 }
337
338 // Check simple extension
339 const ext = filename.split('.').pop()?.toLowerCase() ?? ''
340 if (EXTENSION_ICONS[ext]) {
341 return EXTENSION_ICONS[ext]
342 }
343
344 return DEFAULT_ICON
345}