diff --git a/client/web-sveltekit/BUILD.bazel b/client/web-sveltekit/BUILD.bazel
index 01f96b9a072..2555c0564c9 100644
--- a/client/web-sveltekit/BUILD.bazel
+++ b/client/web-sveltekit/BUILD.bazel
@@ -82,7 +82,10 @@ BUILD_DEPS = [
":node_modules/@graphql-codegen/typescript",
":node_modules/@graphql-codegen/typescript-operations",
":node_modules/@graphql-tools/utils",
+ ":node_modules/@iconify-json/devicon-plain",
":node_modules/@iconify-json/lucide",
+ ":node_modules/@iconify-json/ph",
+ ":node_modules/@iconify-json/simple-icons",
":node_modules/@melt-ui/svelte",
":node_modules/@sentry/sveltekit",
":node_modules/@sourcegraph/branded",
diff --git a/client/web-sveltekit/package.json b/client/web-sveltekit/package.json
index 1dfe4f66708..31482f0d3e0 100644
--- a/client/web-sveltekit/package.json
+++ b/client/web-sveltekit/package.json
@@ -31,7 +31,10 @@
"@graphql-codegen/typescript-operations": "^4.0.1",
"@graphql-tools/utils": "^10.0.11",
"@graphql-typed-document-node/core": "^3.2.0",
+ "@iconify-json/devicon-plain": "^1.1.42",
"@iconify-json/lucide": "^1.1.188",
+ "@iconify-json/ph": "^1.1.13",
+ "@iconify-json/simple-icons": "^1.1.104",
"@playwright/test": "1.42.1",
"@storybook/addon-essentials": "^8.0.5",
"@storybook/addon-interactions": "^7.2.0",
diff --git a/client/web-sveltekit/src/auto-imports.d.ts b/client/web-sveltekit/src/auto-imports.d.ts
index 0faed7228ee..312a85e1a55 100644
--- a/client/web-sveltekit/src/auto-imports.d.ts
+++ b/client/web-sveltekit/src/auto-imports.d.ts
@@ -5,6 +5,7 @@
// Generated by unplugin-auto-import
export {}
declare global {
+ const IDeviconPlainJava: typeof import('~icons/devicon-plain/java')['default']
const ILucideArrowDownFromLine: typeof import('~icons/lucide/arrow-down-from-line')['default']
const ILucideArrowLeftFromLine: typeof import('~icons/lucide/arrow-left-from-line')['default']
const ILucideArrowRightFromLine: typeof import('~icons/lucide/arrow-right-from-line')['default']
@@ -13,7 +14,13 @@ declare global {
const ILucideChevronLast: typeof import('~icons/lucide/chevron-last')['default']
const ILucideChevronLeft: typeof import('~icons/lucide/chevron-left')['default']
const ILucideChevronRight: typeof import('~icons/lucide/chevron-right')['default']
+ const ILucideDatabase: typeof import('~icons/lucide/database')['default']
+ const ILucideEarth: typeof import('~icons/lucide/earth')['default']
const ILucideEllipsis: typeof import('~icons/lucide/ellipsis')['default']
+ const ILucideFileCode: typeof import('~icons/lucide/file-code')['default']
+ const ILucideFileJson: typeof import('~icons/lucide/file-json')['default']
+ const ILucideFileTerminal: typeof import('~icons/lucide/file-terminal')['default']
+ const ILucideFileText: typeof import('~icons/lucide/file-text')['default']
const ILucideFolder: typeof import('~icons/lucide/folder')['default']
const ILucideGitCompareArrows: typeof import('~icons/lucide/git-compare-arrows')['default']
const ILucideGitMerge: typeof import('~icons/lucide/git-merge')['default']
@@ -23,7 +30,77 @@ declare global {
const ILucidePanelLeftClose: typeof import('~icons/lucide/panel-left-close')['default']
const ILucidePanelLeftOpen: typeof import('~icons/lucide/panel-left-open')['default']
const ILucideRegex: typeof import('~icons/lucide/regex')['default']
+ const ILucideSettings: typeof import('~icons/lucide/settings')['default']
+ const ILucideSetttings: typeof import('~icons/lucide/setttings')['default']
const ILucideSquareSlash: typeof import('~icons/lucide/square-slash')['default']
const ILucideStar: typeof import('~icons/lucide/star')['default']
const ILucideX: typeof import('~icons/lucide/x')['default']
+ const IPhFileJpgLight: typeof import('~icons/ph/file-jpg-light')['default']
+ const IPhFilePngLight: typeof import('~icons/ph/file-png-light')['default']
+ const IPhGifFill: typeof import('~icons/ph/gif-fill')['default']
+ const IPhJpgLight: typeof import('~icons/ph/jpg-light')['default']
+ const IPhPngLight: typeof import('~icons/ph/png-light')['default']
+ const IPhPnglight: typeof import('~icons/ph/pnglight')['default']
+ const IPhosphorPngLight: typeof import('~icons/ph/osphor-png-light')['default']
+ const IPhosphorePngLight: typeof import('~icons/ph/osphore-png-light')['default']
+ const ISimpleIconsApachegroovy: typeof import('~icons/simple-icons/apachegroovy')['default']
+ const ISimpleIconsC: typeof import('~icons/simple-icons/c')['default']
+ const ISimpleIconsCSS3: typeof import('~icons/simple-icons/c-s-s3')['default']
+ const ISimpleIconsClojure: typeof import('~icons/simple-icons/clojure')['default']
+ const ISimpleIconsCmake: typeof import('~icons/simple-icons/cmake')['default']
+ const ISimpleIconsCoffeescript: typeof import('~icons/simple-icons/coffeescript')['default']
+ const ISimpleIconsCplusplus: typeof import('~icons/simple-icons/cplusplus')['default']
+ const ISimpleIconsCrystal: typeof import('~icons/simple-icons/crystal')['default']
+ const ISimpleIconsCsharp: typeof import('~icons/simple-icons/csharp')['default']
+ const ISimpleIconsCss3: typeof import('~icons/simple-icons/css3')['default']
+ const ISimpleIconsD: typeof import('~icons/simple-icons/d')['default']
+ const ISimpleIconsDart: typeof import('~icons/simple-icons/dart')['default']
+ const ISimpleIconsDocker: typeof import('~icons/simple-icons/docker')['default']
+ const ISimpleIconsEditorconfig: typeof import('~icons/simple-icons/editorconfig')['default']
+ const ISimpleIconsElixir: typeof import('~icons/simple-icons/elixir')['default']
+ const ISimpleIconsElm: typeof import('~icons/simple-icons/elm')['default']
+ const ISimpleIconsErlang: typeof import('~icons/simple-icons/erlang')['default']
+ const ISimpleIconsFortran: typeof import('~icons/simple-icons/fortran')['default']
+ const ISimpleIconsFsharp: typeof import('~icons/simple-icons/fsharp')['default']
+ const ISimpleIconsGit: typeof import('~icons/simple-icons/git')['default']
+ const ISimpleIconsGnuemacs: typeof import('~icons/simple-icons/gnuemacs')['default']
+ const ISimpleIconsGo: typeof import('~icons/simple-icons/go')['default']
+ const ISimpleIconsGraphql: typeof import('~icons/simple-icons/graphql')['default']
+ const ISimpleIconsHaskell: typeof import('~icons/simple-icons/haskell')['default']
+ const ISimpleIconsHtml5: typeof import('~icons/simple-icons/html5')['default']
+ const ISimpleIconsJavascript: typeof import('~icons/simple-icons/javascript')['default']
+ const ISimpleIconsJinja: typeof import('~icons/simple-icons/jinja')['default']
+ const ISimpleIconsJpeg: typeof import('~icons/simple-icons/jpeg')['default']
+ const ISimpleIconsJulia: typeof import('~icons/simple-icons/julia')['default']
+ const ISimpleIconsKotlin: typeof import('~icons/simple-icons/kotlin')['default']
+ const ISimpleIconsLlvm: typeof import('~icons/simple-icons/llvm')['default']
+ const ISimpleIconsLua: typeof import('~icons/simple-icons/lua')['default']
+ const ISimpleIconsMarkdown: typeof import('~icons/simple-icons/markdown')['default']
+ const ISimpleIconsNginx: typeof import('~icons/simple-icons/nginx')['default']
+ const ISimpleIconsNim: typeof import('~icons/simple-icons/nim')['default']
+ const ISimpleIconsNixos: typeof import('~icons/simple-icons/nixos')['default']
+ const ISimpleIconsNpm: typeof import('~icons/simple-icons/npm')['default']
+ const ISimpleIconsOcaml: typeof import('~icons/simple-icons/ocaml')['default']
+ const ISimpleIconsPerl: typeof import('~icons/simple-icons/perl')['default']
+ const ISimpleIconsPhp: typeof import('~icons/simple-icons/php')['default']
+ const ISimpleIconsPurescript: typeof import('~icons/simple-icons/purescript')['default']
+ const ISimpleIconsPython: typeof import('~icons/simple-icons/python')['default']
+ const ISimpleIconsR: typeof import('~icons/simple-icons/r')['default']
+ const ISimpleIconsRuby: typeof import('~icons/simple-icons/ruby')['default']
+ const ISimpleIconsRust: typeof import('~icons/simple-icons/rust')['default']
+ const ISimpleIconsSass: typeof import('~icons/simple-icons/sass')['default']
+ const ISimpleIconsScala: typeof import('~icons/simple-icons/scala')['default']
+ const ISimpleIconsSvelte: typeof import('~icons/simple-icons/svelte')['default']
+ const ISimpleIconsSvg: typeof import('~icons/simple-icons/svg')['default']
+ const ISimpleIconsSwift: typeof import('~icons/simple-icons/swift')['default']
+ const ISimpleIconsTerraform: typeof import('~icons/simple-icons/terraform')['default']
+ const ISimpleIconsToml: typeof import('~icons/simple-icons/toml')['default']
+ const ISimpleIconsTypescript: typeof import('~icons/simple-icons/typescript')['default']
+ const ISimpleIconsUnrealengine: typeof import('~icons/simple-icons/unrealengine')['default']
+ const ISimpleIconsVim: typeof import('~icons/simple-icons/vim')['default']
+ const ISimpleIconsVisualbasic: typeof import('~icons/simple-icons/visualbasic')['default']
+ const ISimpleIconsVuedotjs: typeof import('~icons/simple-icons/vuedotjs')['default']
+ const ISimpleIconsWebassembly: typeof import('~icons/simple-icons/webassembly')['default']
+ const ISimpleIconsWolframmathematica: typeof import('~icons/simple-icons/wolframmathematica')['default']
+ const ISimpleIconsZig: typeof import('~icons/simple-icons/zig')['default']
}
diff --git a/client/web-sveltekit/src/lib/Icon2.svelte b/client/web-sveltekit/src/lib/Icon2.svelte
index 7ed1a092ce6..d963fe29503 100644
--- a/client/web-sveltekit/src/lib/Icon2.svelte
+++ b/client/web-sveltekit/src/lib/Icon2.svelte
@@ -30,4 +30,4 @@
export let inline: boolean = false
-
+
diff --git a/client/web-sveltekit/src/lib/LanguageIcon.svelte b/client/web-sveltekit/src/lib/LanguageIcon.svelte
index d668d01ffc5..a989232594c 100644
--- a/client/web-sveltekit/src/lib/LanguageIcon.svelte
+++ b/client/web-sveltekit/src/lib/LanguageIcon.svelte
@@ -1,15 +1,18 @@
-
+
+
+
diff --git a/client/web-sveltekit/src/lib/repo/FileIcon.svelte b/client/web-sveltekit/src/lib/repo/FileIcon.svelte
index 6ef24e0ad42..b0200b9d056 100644
--- a/client/web-sveltekit/src/lib/repo/FileIcon.svelte
+++ b/client/web-sveltekit/src/lib/repo/FileIcon.svelte
@@ -1,16 +1,21 @@
-
+
diff --git a/client/web-sveltekit/src/lib/search/dynamicFilters/Sidebar.svelte b/client/web-sveltekit/src/lib/search/dynamicFilters/Sidebar.svelte
index c33e7277ae2..01143c7a393 100644
--- a/client/web-sveltekit/src/lib/search/dynamicFilters/Sidebar.svelte
+++ b/client/web-sveltekit/src/lib/search/dynamicFilters/Sidebar.svelte
@@ -156,7 +156,7 @@
onFilterSelect={handleFilterSelect}
>
-
+
{label}
diff --git a/client/web-sveltekit/src/lib/wildcard/index.ts b/client/web-sveltekit/src/lib/wildcard/index.ts
index 382959cb5d2..26edee5740f 100644
--- a/client/web-sveltekit/src/lib/wildcard/index.ts
+++ b/client/web-sveltekit/src/lib/wildcard/index.ts
@@ -15,4 +15,4 @@ export { default as Input } from './Input.svelte'
export { default as PanelGroup } from './resizable-panel/PanelGroup.svelte'
export { default as Panel } from './resizable-panel/Panel.svelte'
export { default as PanelResizeHandle } from './resizable-panel/PanelResizeHandle.svelte'
-export { getFileIconInfo } from '@sourcegraph/wildcard/src/components/Icon'
+export { getFileIconInfo, DEFAULT_ICON_COLOR } from './language-icons'
diff --git a/client/web-sveltekit/src/lib/wildcard/language-icons.ts b/client/web-sveltekit/src/lib/wildcard/language-icons.ts
new file mode 100644
index 00000000000..be6678ffe7f
--- /dev/null
+++ b/client/web-sveltekit/src/lib/wildcard/language-icons.ts
@@ -0,0 +1,152 @@
+import type { ComponentType, SvelteComponent } from 'svelte'
+import type { SvelteHTMLElements } from 'svelte/elements'
+
+interface LanguageIcon {
+ icon: ComponentType>
+ color: string
+}
+
+const BLUE = 'var(--blue)'
+const PINK = 'var(--pink)'
+const YELLOW = 'var(--yellow)'
+const RED = 'var(--red)'
+const GREEN = 'var(--green)'
+const CYAN = 'var(--blue)'
+const GRAY = 'var(--gray-05)'
+export const DEFAULT_ICON_COLOR = GRAY
+
+/**
+ * The keys of this map must be present in the list of `languageFilter.ALL_LANGUAGES`.
+ *
+ * This map is deliberately not public, use {@link getFileIconInfo} instead.
+ *
+ * See FIXME(id: language-detection) for context on why this map uses the
+ * language as the key instead of something simpler like a file extension.
+ */
+export const FILE_ICONS_BY_LANGUAGE: Map = new Map([
+ ['Bash', { icon: ILucideFileTerminal, color: DEFAULT_ICON_COLOR }],
+ ['BASIC', { icon: ISimpleIconsVisualbasic, color: DEFAULT_ICON_COLOR }],
+ ['C', { icon: ISimpleIconsC, color: BLUE }],
+ ['C++', { icon: ISimpleIconsCplusplus, color: BLUE }],
+ ['C#', { icon: ISimpleIconsCsharp, color: BLUE }],
+ ['Clojure', { icon: ISimpleIconsClojure, color: BLUE }],
+ ['CMake', { icon: ISimpleIconsCmake, color: DEFAULT_ICON_COLOR }],
+ ['CoffeeScript', { icon: ISimpleIconsCoffeescript, color: DEFAULT_ICON_COLOR }],
+
+ // TODO: Decide icon for CSV?
+ ['Crystal', { icon: ISimpleIconsCrystal, color: BLUE }],
+ ['CSS', { icon: ISimpleIconsCss3, color: BLUE }],
+ ['D', { icon: ISimpleIconsD, color: RED }],
+ ['Dart', { icon: ISimpleIconsDart, color: BLUE }],
+ ['Dockerfile', { icon: ISimpleIconsDocker, color: BLUE }],
+ ['EditorConfig', { icon: ISimpleIconsEditorconfig, color: DEFAULT_ICON_COLOR }],
+ ['Elixir', { icon: ISimpleIconsElixir, color: BLUE }],
+ ['Elm', { icon: ISimpleIconsElm, color: BLUE }],
+ ['Emacs Lisp', { icon: ISimpleIconsGnuemacs, color: DEFAULT_ICON_COLOR }],
+ ['Erlang', { icon: ISimpleIconsErlang, color: BLUE }],
+ ['Fortran', { icon: ISimpleIconsFortran, color: DEFAULT_ICON_COLOR }],
+ ['Fortran Free Form', { icon: ISimpleIconsFortran, color: DEFAULT_ICON_COLOR }],
+ ['F#', { icon: ISimpleIconsFsharp, color: BLUE }],
+ ['Git Attributes', { icon: ISimpleIconsGit, color: RED }],
+ ['Go', { icon: ISimpleIconsGo, color: BLUE }],
+ ['Go Module', { icon: ISimpleIconsGo, color: PINK }],
+ ['Go Checksums', { icon: ISimpleIconsGo, color: PINK }],
+ ['Groovy', { icon: ISimpleIconsApachegroovy, color: BLUE }],
+ ['GraphQL', { icon: ISimpleIconsGraphql, color: PINK }],
+ ['Haskell', { icon: ISimpleIconsHaskell, color: BLUE }],
+ ['HTML', { icon: ISimpleIconsHtml5, color: BLUE }],
+ ['HTML+ECR', { icon: ISimpleIconsCrystal, color: BLUE }],
+ ['HTML+EEX', { icon: ISimpleIconsElixir, color: BLUE }],
+ ['HTML+ERB', { icon: ISimpleIconsRuby, color: BLUE }],
+ ['HTML+PHP', { icon: ISimpleIconsPhp, color: BLUE }],
+ ['HTML+Razor', { icon: ISimpleIconsCsharp, color: BLUE }],
+ ['Ignore List', { icon: ILucideSettings, color: DEFAULT_ICON_COLOR }],
+ ['Java', { icon: IDeviconPlainJava, color: DEFAULT_ICON_COLOR }],
+ ['JavaScript', { icon: ISimpleIconsJavascript, color: YELLOW }],
+ ['Jinja', { icon: ISimpleIconsJinja, color: DEFAULT_ICON_COLOR }],
+ ['JSON with Comments', { icon: ILucideFileJson, color: DEFAULT_ICON_COLOR }],
+ ['JSON', { icon: ILucideFileJson, color: DEFAULT_ICON_COLOR }],
+ ['JSON5', { icon: ILucideFileJson, color: DEFAULT_ICON_COLOR }],
+ ['JSONLD', { icon: ILucideFileJson, color: DEFAULT_ICON_COLOR }],
+ ['Julia', { icon: ISimpleIconsJulia, color: DEFAULT_ICON_COLOR }],
+ ['Kotlin', { icon: ISimpleIconsKotlin, color: GREEN }],
+ ['LLVM', { icon: ISimpleIconsLlvm, color: GRAY }],
+ ['Lua', { icon: ISimpleIconsLua, color: BLUE }],
+ ['Markdown', { icon: ISimpleIconsMarkdown, color: BLUE }],
+ ['Mathematica', { icon: ISimpleIconsWolframmathematica, color: RED }],
+
+ // https://github.com/NCAR/ncl, not tweag/nickel
+ ['NCL', { icon: ILucideEarth, color: DEFAULT_ICON_COLOR }],
+ ['Nginx', { icon: ISimpleIconsNginx, color: DEFAULT_ICON_COLOR }],
+ ['Nim', { icon: ISimpleIconsNim, color: YELLOW }],
+ ['Nix', { icon: ISimpleIconsNixos, color: GRAY }],
+ ['NPM Config', { icon: ISimpleIconsNpm, color: RED }],
+
+ // Missing an icon for Objective-C
+ ['OCaml', { icon: ISimpleIconsOcaml, color: YELLOW }],
+ ['PHP', { icon: ISimpleIconsPhp, color: CYAN }],
+ ['Perl', { icon: ISimpleIconsPerl, color: DEFAULT_ICON_COLOR }],
+ ['PLpgSQL', { icon: ILucideDatabase, color: BLUE }],
+ ['PowerShell', { icon: ILucideFileTerminal, color: DEFAULT_ICON_COLOR }],
+
+ // Missing icon for Protobuf
+ ['PureScript', { icon: ISimpleIconsPurescript, color: DEFAULT_ICON_COLOR }],
+ ['Python', { icon: ISimpleIconsPython, color: BLUE }],
+ ['R', { icon: ISimpleIconsR, color: RED }],
+ ['Ruby', { icon: ISimpleIconsRuby, color: RED }],
+ ['Rust', { icon: ISimpleIconsRust, color: DEFAULT_ICON_COLOR }],
+ ['Scala', { icon: ISimpleIconsScala, color: RED }],
+ ['Sass', { icon: ISimpleIconsSass, color: PINK }],
+ ['SCSS', { icon: ISimpleIconsSass, color: PINK }],
+ ['SQL', { icon: ILucideDatabase, color: BLUE }],
+
+ // Missing icon for Starlark
+ ['Svelte', { icon: ISimpleIconsSvelte, color: RED }],
+ ['SVG', { icon: ISimpleIconsSvg, color: YELLOW }],
+ ['Swift', { icon: ISimpleIconsSwift, color: BLUE }],
+ ['Terraform', { icon: ISimpleIconsTerraform, color: BLUE }],
+ ['TSX', { icon: ISimpleIconsTypescript, color: BLUE }],
+ ['TypeScript', { icon: ISimpleIconsTypescript, color: BLUE }],
+ ['Text', { icon: ILucideFileText, color: DEFAULT_ICON_COLOR }],
+
+ // Missing icon for Thrift
+ ['TOML', { icon: ISimpleIconsToml, color: DEFAULT_ICON_COLOR }],
+ ['UnrealScript', { icon: ISimpleIconsUnrealengine, color: DEFAULT_ICON_COLOR }],
+ ['VBA', { icon: ISimpleIconsVisualbasic, color: BLUE }],
+ ['VBScript', { icon: ISimpleIconsVisualbasic, color: BLUE }],
+ ['Vim Script', { icon: ISimpleIconsVim, color: DEFAULT_ICON_COLOR }],
+ ['Vue', { icon: ISimpleIconsVuedotjs, color: GREEN }],
+ ['WebAssembly', { icon: ISimpleIconsWebassembly, color: BLUE }],
+ ['XML', { icon: ILucideSettings, color: DEFAULT_ICON_COLOR }],
+ ['YAML', { icon: ILucideSettings, color: DEFAULT_ICON_COLOR }],
+ ['Zig', { icon: ISimpleIconsZig, color: YELLOW }],
+])
+
+/**
+ * DO NOT add any extensions here for which there are multiple different
+ * file formats in practice which use the same extensions.
+ *
+ * For programming languages, update {@link FILE_ICONS_BY_LANGUAGE}.
+ */
+const BINARY_FILE_ICONS_BY_EXTENSION: Map = new Map([
+ ['gif', { icon: IPhGifFill, color: DEFAULT_ICON_COLOR }],
+ ['giff', { icon: IPhGifFill, color: DEFAULT_ICON_COLOR }],
+ ['jpg', { icon: IPhFileJpgLight, color: YELLOW }],
+ ['jpeg', { icon: IPhFileJpgLight, color: YELLOW }],
+ ['png', { icon: IPhFilePngLight, color: DEFAULT_ICON_COLOR }],
+])
+
+/**
+ *
+ * See FIXME(id: language-detection) for context on why this takes a
+ * languages argument instead of directly using the file extension
+ * for determining the language.
+ *
+ * @param path The path of the file (or just its name).
+ * @param language Alias to the file language name.
+ * @returns undefined if the language is not a known language.
+ */
+export function getFileIconInfo(path: string, language: string): LanguageIcon | undefined {
+ const extension = path.split('.').at(-1) ?? ''
+ return BINARY_FILE_ICONS_BY_EXTENSION.get(extension) ?? FILE_ICONS_BY_LANGUAGE.get(language)
+}
diff --git a/client/wildcard/BUILD.bazel b/client/wildcard/BUILD.bazel
index 609cbb3c728..e531f392019 100644
--- a/client/wildcard/BUILD.bazel
+++ b/client/wildcard/BUILD.bazel
@@ -565,6 +565,7 @@ ts_project(
"//:node_modules/js-cookie",
"//:node_modules/mdi-react",
"//:node_modules/react",
+ "//:node_modules/react-icons",
"//:node_modules/rxjs",
"//:node_modules/sinon",
"//:node_modules/vitest",
diff --git a/client/wildcard/src/components/Icon/language-icon/LanguageIcon.tsx b/client/wildcard/src/components/Icon/language-icon/LanguageIcon.tsx
index 75bd5e10dcc..7377ddf4ac8 100644
--- a/client/wildcard/src/components/Icon/language-icon/LanguageIcon.tsx
+++ b/client/wildcard/src/components/Icon/language-icon/LanguageIcon.tsx
@@ -24,8 +24,8 @@ export const LanguageIcon: FC = props => {
if (fileIcon) {
return (
)
diff --git a/client/wildcard/src/components/Icon/language-icon/language-icons.test.ts b/client/wildcard/src/components/Icon/language-icon/language-icons.test.ts
index 48b5a024c96..960edcf4b36 100644
--- a/client/wildcard/src/components/Icon/language-icon/language-icons.test.ts
+++ b/client/wildcard/src/components/Icon/language-icon/language-icons.test.ts
@@ -1,50 +1,35 @@
-import { mdiFileCodeOutline, mdiFilePngBox, mdiLanguageJavascript } from '@mdi/js'
+import { PiFilePngLight } from 'react-icons/pi'
+import { SiJavascript } from 'react-icons/si'
import { describe, expect, it } from 'vitest'
import { getFileIconInfo } from './language-icons'
describe('getFileIconInfo', () => {
- const tests: {
- name: string
- file: string
- language: string
- expectedSvgPath: string | undefined
- expectedIsTest: boolean
- }[] = [
+ const tests = [
{
name: 'check that png works',
file: 'myfile.png',
language: '',
- expectedSvgPath: mdiFilePngBox,
- expectedIsTest: false,
+ expectedIcon: PiFilePngLight,
},
{
name: 'works with simple file name',
file: 'my-file.js',
language: 'JavaScript',
- expectedSvgPath: mdiLanguageJavascript,
- expectedIsTest: false,
- },
- {
- name: 'check fallback behavior',
- file: 'placeholder',
- language: 'Vim Script',
- expectedSvgPath: mdiFileCodeOutline,
- expectedIsTest: false,
+ expectedIcon: SiJavascript,
},
{
name: 'check unknown language',
file: 'my-file.test.unknown',
language: 'Unknown',
- expectedSvgPath: undefined,
- expectedIsTest: true,
+ expectedIcon: undefined,
},
]
for (const t of tests) {
it(t.name, () => {
const iconInfo = getFileIconInfo(t.file, t.language)
- expect(iconInfo?.svg.path).toBe(t.expectedSvgPath)
+ expect(iconInfo?.icon).toBe(t.expectedIcon)
})
}
})
diff --git a/client/wildcard/src/components/Icon/language-icon/language-icons.ts b/client/wildcard/src/components/Icon/language-icon/language-icons.ts
index de688680e35..d33b212454a 100644
--- a/client/wildcard/src/components/Icon/language-icon/language-icons.ts
+++ b/client/wildcard/src/components/Icon/language-icon/language-icons.ts
@@ -1,57 +1,5 @@
import type { ComponentType } from 'react'
-// TODO(id: md-icons-and-react-icons)
-//
-// We're using react-icons for the React version of the web app
-// since it has a large number of icons. However, those aren't
-// usable in SvelteKit as the icons are React components.
-//
-// So we also use Material Design icons which are exposed as SVGs.
-// However, this has two drawbacks:
-// - It has many fewer languages compared to react-icons.
-// - A future version of Material Design icons will remove programming
-// language and file type icons.
-// https://github.com/Templarian/MaterialDesign/issues/6602
-//
-// It would be valuable to explore other icon libraries that can
-// be used both by React and SvelteKit or make our own.
-import {
- mdiCodeJson,
- mdiCog,
- mdiConsole,
- mdiDocker,
- mdiEarth,
- mdiFileCodeOutline,
- mdiFileGifBox,
- mdiFileJpgBox,
- mdiFilePngBox,
- mdiGit,
- mdiGraphql,
- mdiLanguageC,
- mdiLanguageCpp,
- mdiLanguageCsharp,
- mdiLanguageCss3,
- mdiLanguageGo,
- mdiLanguageHaskell,
- mdiLanguageHtml5,
- mdiLanguageJava,
- mdiLanguageJavascript,
- mdiLanguageKotlin,
- mdiLanguageLua,
- mdiLanguageMarkdown,
- mdiLanguagePhp,
- mdiLanguagePython,
- mdiLanguageR,
- mdiLanguageRuby,
- mdiLanguageRust,
- mdiLanguageSwift,
- mdiLanguageTypescript,
- mdiNix,
- mdiNpm,
- mdiSass,
- mdiSvg,
- mdiText,
-} from '@mdi/js'
import { CiSettings, CiTextAlignLeft } from 'react-icons/ci'
import { FaCss3Alt, FaSass, FaVuejs } from 'react-icons/fa'
import { GoDatabase, GoTerminal } from 'react-icons/go'
@@ -123,21 +71,11 @@ import styles from './LanguageIcon.module.scss'
export type CustomIcon = ComponentType<{ className?: string }>
-export interface ReactIcon {
+export interface IconInfo {
icon: CustomIcon
className: string
}
-export interface SvgIcon {
- path: string
- color: string
-}
-
-interface UnifiedIcon {
- react: ReactIcon
- svg?: SvgIcon['path']
-}
-
/**
* The keys of this map must be present in the list of `languageFilter.ALL_LANGUAGES`.
*
@@ -146,133 +84,119 @@ interface UnifiedIcon {
* See FIXME(id: language-detection) for context on why this map uses the
* language as the key instead of something simpler like a file extension.
*/
-export const FILE_ICONS_BY_LANGUAGE: Map = new Map([
- ['Bash', { react: { icon: GoTerminal, className: styles.defaultIcon }, svg: mdiConsole }],
- ['BASIC', { react: { icon: SiVisualbasic, className: styles.defaultIcon } }],
- ['C', { react: { icon: SiC, className: styles.blue }, svg: mdiLanguageC }],
- ['C++', { react: { icon: SiCplusplus, className: styles.blue }, svg: mdiLanguageCpp }],
- ['C#', { react: { icon: SiCsharp, className: styles.blue }, svg: mdiLanguageCsharp }],
- ['Clojure', { react: { icon: SiClojure, className: styles.blue } }],
- ['CMake', { react: { icon: SiCmake, className: styles.defaultIcon } }],
- ['CoffeeScript', { react: { icon: SiCoffeescript, className: styles.defaultIcon } }],
+export const FILE_ICONS_BY_LANGUAGE: Map = new Map([
+ ['Bash', { icon: GoTerminal, className: styles.defaultIcon }],
+ ['BASIC', { icon: SiVisualbasic, className: styles.defaultIcon }],
+ ['C', { icon: SiC, className: styles.blue }],
+ ['C++', { icon: SiCplusplus, className: styles.blue }],
+ ['C#', { icon: SiCsharp, className: styles.blue }],
+ ['Clojure', { icon: SiClojure, className: styles.blue }],
+ ['CMake', { icon: SiCmake, className: styles.defaultIcon }],
+ ['CoffeeScript', { icon: SiCoffeescript, className: styles.defaultIcon }],
// TODO: Decide icon for CSV?
- ['Crystal', { react: { icon: SiCrystal, className: styles.blue } }],
- ['CSS', { react: { icon: FaCss3Alt, className: styles.blue }, svg: mdiLanguageCss3 }],
- ['D', { react: { icon: SiD, className: styles.red } }],
- ['Dart', { react: { icon: SiDart, className: styles.blue } }],
- ['Dockerfile', { react: { icon: SiDocker, className: styles.blue }, svg: mdiDocker }],
- ['EditorConfig', { react: { icon: SiEditorconfig, className: styles.defaultIcon } }],
- ['Elixir', { react: { icon: SiElixir, className: styles.blue } }],
- ['Elm', { react: { icon: SiElm, className: styles.blue } }],
- ['Emacs Lisp', { react: { icon: SiGnuemacs, className: styles.defaultIcon } }],
- ['Erlang', { react: { icon: SiErlang, className: styles.blue } }],
- ['Fortran', { react: { icon: SiFortran, className: styles.defaultIcon } }],
- ['Fortran Free Form', { react: { icon: SiFortran, className: styles.defaultIcon } }],
- ['F#', { react: { icon: SiFsharp, className: styles.blue } }],
- ['Git Attributes', { react: { icon: SiGit, className: styles.red }, svg: mdiGit }],
- ['Go', { react: { icon: SiGo, className: styles.blue }, svg: mdiLanguageGo }],
- ['Go Module', { react: { icon: SiGo, className: styles.pink }, svg: mdiLanguageGo }],
- ['Go Checksums', { react: { icon: SiGo, className: styles.pink }, svg: mdiLanguageGo }],
- ['Groovy', { react: { icon: SiApachegroovy, className: styles.blue } }],
- ['GraphQL', { react: { icon: SiGraphql, className: styles.pink }, svg: mdiGraphql }],
- ['Haskell', { react: { icon: SiHaskell, className: styles.blue }, svg: mdiLanguageHaskell }],
- ['HTML', { react: { icon: SiHtml5, className: styles.blue }, svg: mdiLanguageHtml5 }],
- ['HTML+ECR', { react: { icon: SiCrystal, className: styles.blue } }],
- ['HTML+EEX', { react: { icon: SiElixir, className: styles.blue } }],
- ['HTML+ERB', { react: { icon: SiRuby, className: styles.blue } }],
- ['HTML+PHP', { react: { icon: SiPhp, className: styles.blue } }],
- ['HTML+Razor', { react: { icon: SiCsharp, className: styles.blue } }],
- ['Ignore List', { react: { icon: CiSettings, className: styles.defaultIcon }, svg: mdiCog }],
- ['Java', { react: { icon: GrJava, className: styles.defaultIcon }, svg: mdiLanguageJava }],
- ['JavaScript', { react: { icon: SiJavascript, className: styles.yellow }, svg: mdiLanguageJavascript }],
- ['Jinja', { react: { icon: SiJinja, className: styles.defaultIcon } }],
- ['JSON with Comments', { react: { icon: VscJson, className: styles.defaultIcon } }],
- ['JSON', { react: { icon: VscJson, className: styles.defaultIcon }, svg: mdiCodeJson }],
- ['JSON5', { react: { icon: VscJson, className: styles.defaultIcon }, svg: mdiCodeJson }],
- ['JSONLD', { react: { icon: VscJson, className: styles.defaultIcon }, svg: mdiCodeJson }],
- ['Julia', { react: { icon: SiJulia, className: styles.defaultIcon } }],
- ['Kotlin', { react: { icon: SiKotlin, className: styles.green }, svg: mdiLanguageKotlin }],
- ['LLVM', { react: { icon: SiLlvm, className: styles.gray } }],
- ['Lua', { react: { icon: SiLua, className: styles.blue }, svg: mdiLanguageLua }],
- ['Markdown', { react: { icon: SiMarkdown, className: styles.blue }, svg: mdiLanguageMarkdown }],
- ['Mathematica', { react: { icon: SiWolframmathematica, className: styles.red } }],
+ ['Crystal', { icon: SiCrystal, className: styles.blue }],
+ ['CSS', { icon: FaCss3Alt, className: styles.blue }],
+ ['D', { icon: SiD, className: styles.red }],
+ ['Dart', { icon: SiDart, className: styles.blue }],
+ ['Dockerfile', { icon: SiDocker, className: styles.blue }],
+ ['EditorConfig', { icon: SiEditorconfig, className: styles.defaultIcon }],
+ ['Elixir', { icon: SiElixir, className: styles.blue }],
+ ['Elm', { icon: SiElm, className: styles.blue }],
+ ['Emacs Lisp', { icon: SiGnuemacs, className: styles.defaultIcon }],
+ ['Erlang', { icon: SiErlang, className: styles.blue }],
+ ['Fortran', { icon: SiFortran, className: styles.defaultIcon }],
+ ['Fortran Free Form', { icon: SiFortran, className: styles.defaultIcon }],
+ ['F#', { icon: SiFsharp, className: styles.blue }],
+ ['Git Attributes', { icon: SiGit, className: styles.red }],
+ ['Go', { icon: SiGo, className: styles.blue }],
+ ['Go Module', { icon: SiGo, className: styles.pink }],
+ ['Go Checksums', { icon: SiGo, className: styles.pink }],
+ ['Groovy', { icon: SiApachegroovy, className: styles.blue }],
+ ['GraphQL', { icon: SiGraphql, className: styles.pink }],
+ ['Haskell', { icon: SiHaskell, className: styles.blue }],
+ ['HTML', { icon: SiHtml5, className: styles.blue }],
+ ['HTML+ECR', { icon: SiCrystal, className: styles.blue }],
+ ['HTML+EEX', { icon: SiElixir, className: styles.blue }],
+ ['HTML+ERB', { icon: SiRuby, className: styles.blue }],
+ ['HTML+PHP', { icon: SiPhp, className: styles.blue }],
+ ['HTML+Razor', { icon: SiCsharp, className: styles.blue }],
+ ['Ignore List', { icon: CiSettings, className: styles.defaultIcon }],
+ ['Java', { icon: GrJava, className: styles.defaultIcon }],
+ ['JavaScript', { icon: SiJavascript, className: styles.yellow }],
+ ['Jinja', { icon: SiJinja, className: styles.defaultIcon }],
+ ['JSON with Comments', { icon: VscJson, className: styles.defaultIcon }],
+ ['JSON', { icon: VscJson, className: styles.defaultIcon }],
+ ['JSON5', { icon: VscJson, className: styles.defaultIcon }],
+ ['JSONLD', { icon: VscJson, className: styles.defaultIcon }],
+ ['Julia', { icon: SiJulia, className: styles.defaultIcon }],
+ ['Kotlin', { icon: SiKotlin, className: styles.green }],
+ ['LLVM', { icon: SiLlvm, className: styles.gray }],
+ ['Lua', { icon: SiLua, className: styles.blue }],
+ ['Markdown', { icon: SiMarkdown, className: styles.blue }],
+ ['Mathematica', { icon: SiWolframmathematica, className: styles.red }],
// https://github.com/NCAR/ncl, not tweag/nickel
- ['NCL', { react: { icon: ImEarth, className: styles.defaultIcon }, svg: mdiEarth }],
- ['Nginx', { react: { icon: SiNginx, className: styles.defaultIcon } }],
- ['Nim', { react: { icon: SiNim, className: styles.yellow } }],
- ['Nix', { react: { icon: SiNixos, className: styles.gray }, svg: mdiNix }],
- ['NPM Config', { react: { icon: SiNpm, className: styles.red }, svg: mdiNpm }],
+ ['NCL', { icon: ImEarth, className: styles.defaultIcon }],
+ ['Nginx', { icon: SiNginx, className: styles.defaultIcon }],
+ ['Nim', { icon: SiNim, className: styles.yellow }],
+ ['Nix', { icon: SiNixos, className: styles.gray }],
+ ['NPM Config', { icon: SiNpm, className: styles.red }],
// Missing an icon for Objective-C
- ['OCaml', { react: { icon: SiOcaml, className: styles.yellow } }],
- ['PHP', { react: { icon: SiPhp, className: styles.cyan }, svg: mdiLanguagePhp }],
- ['Perl', { react: { icon: SiPerl, className: styles.defaultIcon } }],
- ['PLpgSQL', { react: { icon: GoDatabase, className: styles.blue } }],
- ['PowerShell', { react: { icon: GoTerminal, className: styles.defaultIcon }, svg: mdiConsole }],
+ ['OCaml', { icon: SiOcaml, className: styles.yellow }],
+ ['PHP', { icon: SiPhp, className: styles.cyan }],
+ ['Perl', { icon: SiPerl, className: styles.defaultIcon }],
+ ['PLpgSQL', { icon: GoDatabase, className: styles.blue }],
+ ['PowerShell', { icon: GoTerminal, className: styles.defaultIcon }],
// Missing icon for Protobuf
- ['PureScript', { react: { icon: SiPurescript, className: styles.defaultIcon } }],
- ['Python', { react: { icon: SiPython, className: styles.blue }, svg: mdiLanguagePython }],
- ['R', { react: { icon: SiR, className: styles.red }, svg: mdiLanguageR }],
- ['Ruby', { react: { icon: SiRuby, className: styles.red }, svg: mdiLanguageRuby }],
- ['Rust', { react: { icon: SiRust, className: styles.defaultIcon }, svg: mdiLanguageRust }],
- ['Scala', { react: { icon: SiScala, className: styles.red } }],
- ['Sass', { react: { icon: FaSass, className: styles.pink }, svg: mdiSass }],
- ['SCSS', { react: { icon: FaSass, className: styles.pink } }],
- ['SQL', { react: { icon: GoDatabase, className: styles.blue } }],
+ ['PureScript', { icon: SiPurescript, className: styles.defaultIcon }],
+ ['Python', { icon: SiPython, className: styles.blue }],
+ ['R', { icon: SiR, className: styles.red }],
+ ['Ruby', { icon: SiRuby, className: styles.red }],
+ ['Rust', { icon: SiRust, className: styles.defaultIcon }],
+ ['Scala', { icon: SiScala, className: styles.red }],
+ ['Sass', { icon: FaSass, className: styles.pink }],
+ ['SCSS', { icon: FaSass, className: styles.pink }],
+ ['SQL', { icon: GoDatabase, className: styles.blue }],
// Missing icon for Starlark
- ['Svelte', { react: { icon: SiSvelte, className: styles.red } }],
- ['SVG', { react: { icon: SiSvg, className: styles.yellow }, svg: mdiSvg }],
- ['Swift', { react: { icon: SiSwift, className: styles.blue }, svg: mdiLanguageSwift }],
- ['Terraform', { react: { icon: SiTerraform, className: styles.blue } }],
- ['TSX', { react: { icon: SiTypescript, className: styles.blue }, svg: mdiLanguageTypescript }],
- ['TypeScript', { react: { icon: SiTypescript, className: styles.blue }, svg: mdiLanguageTypescript }],
- ['Text', { react: { icon: CiTextAlignLeft, className: styles.defaultIcon }, svg: mdiText }],
+ ['Svelte', { icon: SiSvelte, className: styles.red }],
+ ['SVG', { icon: SiSvg, className: styles.yellow }],
+ ['Swift', { icon: SiSwift, className: styles.blue }],
+ ['Terraform', { icon: SiTerraform, className: styles.blue }],
+ ['TSX', { icon: SiTypescript, className: styles.blue }],
+ ['TypeScript', { icon: SiTypescript, className: styles.blue }],
+ ['Text', { icon: CiTextAlignLeft, className: styles.defaultIcon }],
// Missing icon for Thrift
- ['TOML', { react: { icon: SiToml, className: styles.defaultIcon } }],
- ['UnrealScript', { react: { icon: SiUnrealengine, className: styles.defaultIcon } }],
- ['VBA', { react: { icon: SiVisualbasic, className: styles.blue } }],
- ['VBScript', { react: { icon: SiVisualbasic, className: styles.blue } }],
- ['Vim Script', { react: { icon: SiVim, className: styles.defaultIcon } }],
- ['Vue', { react: { icon: FaVuejs, className: styles.green } }],
- ['WebAssembly', { react: { icon: SiWebassembly, className: styles.blue } }],
- ['XML', { react: { icon: CiSettings, className: styles.defaultIcon }, svg: mdiCog }],
- ['YAML', { react: { icon: CiSettings, className: styles.defaultIcon }, svg: mdiCog }],
- ['Zig', { react: { icon: SiZig, className: styles.yellow } }],
+ ['TOML', { icon: SiToml, className: styles.defaultIcon }],
+ ['UnrealScript', { icon: SiUnrealengine, className: styles.defaultIcon }],
+ ['VBA', { icon: SiVisualbasic, className: styles.blue }],
+ ['VBScript', { icon: SiVisualbasic, className: styles.blue }],
+ ['Vim Script', { icon: SiVim, className: styles.defaultIcon }],
+ ['Vue', { icon: FaVuejs, className: styles.green }],
+ ['WebAssembly', { icon: SiWebassembly, className: styles.blue }],
+ ['XML', { icon: CiSettings, className: styles.defaultIcon }],
+ ['YAML', { icon: CiSettings, className: styles.defaultIcon }],
+ ['Zig', { icon: SiZig, className: styles.yellow }],
])
-export interface BinaryFileIcon {
- react: ReactIcon
- svg: string
-}
-
/**
* DO NOT add any extensions here for which there are multiple different
* file formats in practice which use the same extensions.
*
* For programming languages, update {@link FILE_ICONS_BY_LANGUAGE}.
*/
-const BINARY_FILE_ICONS_BY_EXTENSION: Map = new Map([
- ['gif', { react: { icon: MdGif, className: styles.defaultIcon }, svg: mdiFileGifBox }],
- ['giff', { react: { icon: MdGif, className: styles.defaultIcon }, svg: mdiFileGifBox }],
- ['jpg', { react: { icon: SiJpeg, className: styles.yellow }, svg: mdiFileJpgBox }],
- ['jpeg', { react: { icon: SiJpeg, className: styles.yellow }, svg: mdiFileJpgBox }],
- ['png', { react: { icon: PiFilePngLight, className: styles.defaultIcon }, svg: mdiFilePngBox }],
+const BINARY_FILE_ICONS_BY_EXTENSION: Map = new Map([
+ ['gif', { icon: MdGif, className: styles.defaultIcon }],
+ ['giff', { icon: MdGif, className: styles.defaultIcon }],
+ ['jpg', { icon: SiJpeg, className: styles.yellow }],
+ ['jpeg', { icon: SiJpeg, className: styles.yellow }],
+ ['png', { icon: PiFilePngLight, className: styles.defaultIcon }],
])
-// See TODO(id: md-icons-and-react-icons) for context
-export interface IconInfo {
- // For use in the React webapp
- react: ReactIcon
-
- // For use in the SvelteKit rewrite
- svg: SvgIcon
-}
-
/**
*
* See FIXME(id: language-detection) for context on why this takes a
@@ -285,58 +209,5 @@ export interface IconInfo {
*/
export function getFileIconInfo(path: string, language: string): IconInfo | undefined {
const extension = path.split('.').at(-1) ?? ''
- const icon1 = BINARY_FILE_ICONS_BY_EXTENSION.get(extension)
-
- if (icon1 !== undefined) {
- return {
- react: icon1.react,
- svg: { path: icon1.svg, color: classNameToColor(icon1.react.className) },
- }
- }
-
- const icon2 = FILE_ICONS_BY_LANGUAGE.get(language)
-
- if (icon2 !== undefined) {
- return {
- react: icon2.react,
- svg: { path: icon2.svg ?? mdiFileCodeOutline, color: classNameToColor(icon2.react.className) },
- }
- }
-
- return
-}
-
-const BLUE = 'var(--blue)'
-const PINK = 'var(--pink)'
-const YELLOW = 'var(--yellow)'
-const RED = 'var(--red)'
-const GREEN = 'var(--green)'
-const CYAN = 'var(--blue)'
-const GRAY = 'var(--gray-05)'
-
-function classNameToColor(name: string): string {
- switch (name) {
- case styles.blue: {
- return BLUE
- }
- case styles.red: {
- return RED
- }
- case styles.yellow: {
- return YELLOW
- }
- case styles.pink: {
- return PINK
- }
- case styles.green: {
- return GREEN
- }
- case styles.cyan: {
- return CYAN
- }
- case styles.gray:
- default: {
- return GRAY
- }
- }
+ return BINARY_FILE_ICONS_BY_EXTENSION.get(extension) ?? FILE_ICONS_BY_LANGUAGE.get(language)
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index a42de46c6f1..dea3349d422 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1639,9 +1639,18 @@ importers:
'@graphql-typed-document-node/core':
specifier: ^3.2.0
version: 3.2.0(graphql@15.4.0)
+ '@iconify-json/devicon-plain':
+ specifier: ^1.1.42
+ version: 1.1.42
'@iconify-json/lucide':
specifier: ^1.1.188
version: 1.1.188
+ '@iconify-json/ph':
+ specifier: ^1.1.13
+ version: 1.1.13
+ '@iconify-json/simple-icons':
+ specifier: ^1.1.104
+ version: 1.1.104
'@playwright/test':
specifier: 1.42.1
version: 1.42.1
@@ -5508,12 +5517,30 @@ packages:
resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==}
dev: true
+ /@iconify-json/devicon-plain@1.1.42:
+ resolution: {integrity: sha512-NGCuw6BHn8lpjbVVa4XvYnprhWZ6IWkr6O19b69ySpDyi8QF3lh/Pe5As7C6eAG1KsblxQFqwcztgILOOmZqAA==}
+ dependencies:
+ '@iconify/types': 2.0.0
+ dev: true
+
/@iconify-json/lucide@1.1.188:
resolution: {integrity: sha512-yJNoU7vX11OvdeSKBiAvmbk/etAq2HPCZQkZX1U687NZhn8dTfx1PfyNhPxtJilrd288XGDKK+NQgygcZ+Ho4g==}
dependencies:
'@iconify/types': 2.0.0
dev: true
+ /@iconify-json/ph@1.1.13:
+ resolution: {integrity: sha512-xtM4JJ63HCKj09WRqrBswXiHrpliBlqboWSZH8odcmqYXbvIFceU9/Til4V+MQr6+MoUC+KB72cxhky2+A6r/g==}
+ dependencies:
+ '@iconify/types': 2.0.0
+ dev: true
+
+ /@iconify-json/simple-icons@1.1.104:
+ resolution: {integrity: sha512-986r56QHsIqa84MdGpV+tUJVhJjDXFb1OfFJZKMDiuQOi0CacK5QsM3if5RNjmT9WhrQtm5uTRHy4/4u7Cb9oQ==}
+ dependencies:
+ '@iconify/types': 2.0.0
+ dev: true
+
/@iconify/types@2.0.0:
resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
dev: true