{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "file-type-icon",
  "title": "File Type Icon",
  "description": "VS Code style file icon from extension or file name via Iconify vscode-icons.",
  "dependencies": [
    "@iconify/react"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "src/components/f-ui/file-type-icon/file-type-icon.tsx",
      "content": "import { Icon } from \"@iconify/react\";\n\nimport { cn } from \"@/lib/utils\";\n\nimport {\n  DEFAULT_FILE_TYPE_FALLBACK_ICON,\n  resolveFileTypeIconifyId,\n} from \"./resolve-file-type-icon\";\nimport { FILE_TYPE_ICON_BY_EXT } from \"./vscode-file-type-map\";\n\nexport type FileTypeIconProps = {\n  extension?: string;\n  fileName?: string;\n  className?: string;\n  size?: number;\n  fallbackIcon?: string;\n  title?: string;\n  \"aria-label\"?: string;\n};\n\nexport function FileTypeIcon({\n  extension,\n  fileName,\n  className,\n  size = 16,\n  fallbackIcon,\n  title,\n  \"aria-label\": ariaLabel,\n}: FileTypeIconProps) {\n  const icon = resolveFileTypeIconifyId({\n    extension,\n    fileName,\n    map: FILE_TYPE_ICON_BY_EXT,\n    fallbackIcon: fallbackIcon ?? DEFAULT_FILE_TYPE_FALLBACK_ICON,\n  });\n\n  const a11y =\n    ariaLabel !== undefined\n      ? { \"aria-label\": ariaLabel, role: \"img\" as const }\n      : { \"aria-hidden\": true as const };\n\n  return (\n    <span className={cn(\"inline-flex shrink-0\", className)} title={title}>\n      <Icon icon={icon} width={size} height={size} {...a11y} />\n    </span>\n  );\n}\n\nexport { DEFAULT_FILE_TYPE_FALLBACK_ICON };\n",
      "type": "registry:component",
      "target": "components/f-ui/file-type-icon/file-type-icon.tsx"
    },
    {
      "path": "src/components/f-ui/file-type-icon/resolve-file-type-icon.ts",
      "content": "/** Longest first: `archive.tar.bz2` before `.gz` substring issues; `foo.d.ts` before `.ts`. */\nexport const COMPOUND_EXTENSIONS_DESC = [\n  \"tar.bz2\",\n  \"tar.gz\",\n  \"tar.xz\",\n  \"d.ts\",\n] as const;\n\nexport const DEFAULT_FILE_TYPE_FALLBACK_ICON = \"vscode-icons:default-file\";\n\nexport function normalizeExtension(raw: string): string {\n  let s = raw.trim();\n  while (s.startsWith(\".\")) {\n    s = s.slice(1);\n  }\n  return s.toLowerCase();\n}\n\nexport function getBasename(pathOrName: string): string {\n  const s = pathOrName.trim();\n  if (!s) return \"\";\n  const normalized = s.replace(/\\\\/g, \"/\");\n  const idx = normalized.lastIndexOf(\"/\");\n  return idx === -1 ? normalized : normalized.slice(idx + 1);\n}\n\n/**\n * Returns a map key for lookup (e.g. \"ts\", \"d.ts\", \"tar.gz\"), or null if none.\n */\nexport function extractExtensionKeyFromFileName(fileName: string): string | null {\n  const base = getBasename(fileName);\n  if (!base) return null;\n  const lower = base.toLowerCase();\n\n  for (const compound of COMPOUND_EXTENSIONS_DESC) {\n    const suffix = `.${compound}`;\n    if (lower.endsWith(suffix)) {\n      return compound;\n    }\n  }\n\n  const dot = base.lastIndexOf(\".\");\n  if (dot <= 0 || dot === base.length - 1) return null;\n\n  return base.slice(dot + 1).toLowerCase();\n}\n\n/**\n * Resolves a lookup key: `extension` wins; then exact basename (e.g. `Dockerfile`,\n * `docker-compose.yml`); then `.env*` / hidden dotfiles; then parsed extension.\n */\nexport function resolveLookupKey(\n  extension: string | undefined,\n  fileName: string | undefined,\n  map: Record<string, string>,\n): string | null {\n  if (extension !== undefined && extension !== \"\") {\n    return normalizeExtension(extension);\n  }\n  if (fileName === undefined || fileName === \"\") {\n    return null;\n  }\n\n  const base = getBasename(fileName);\n  const lower = base.toLowerCase();\n\n  if (map[lower] !== undefined) {\n    return lower;\n  }\n\n  if (lower === \".env\" || lower.startsWith(\".env.\")) {\n    return \"env\";\n  }\n\n  if (\n    lower.startsWith(\".\") &&\n    lower.length > 1 &&\n    !lower.slice(1).includes(\".\")\n  ) {\n    const hiddenKey = lower.slice(1);\n    if (map[hiddenKey] !== undefined) {\n      return hiddenKey;\n    }\n  }\n\n  return extractExtensionKeyFromFileName(fileName);\n}\n\nexport function resolveFileTypeIconifyId(options: {\n  extension?: string;\n  fileName?: string;\n  map: Record<string, string>;\n  fallbackIcon?: string;\n}): string {\n  const fallback = options.fallbackIcon ?? DEFAULT_FILE_TYPE_FALLBACK_ICON;\n\n  const key = resolveLookupKey(\n    options.extension,\n    options.fileName,\n    options.map,\n  );\n\n  if (key === null || key === \"\") {\n    return fallback;\n  }\n\n  const hit = options.map[key];\n  return hit ?? fallback;\n}\n",
      "type": "registry:lib",
      "target": "components/f-ui/file-type-icon/resolve-file-type-icon.ts"
    },
    {
      "path": "src/components/f-ui/file-type-icon/vscode-file-type-map.ts",
      "content": "/** Full Iconify ids. Keys: lowercase, no leading dot. */\nexport const FILE_TYPE_ICON_BY_EXT: Record<string, string> = {\n  \"d.ts\": \"vscode-icons:file-type-typescriptdef\",\n  \"tar.bz2\": \"vscode-icons:file-type-zip\",\n  \"tar.gz\": \"vscode-icons:file-type-zip\",\n  \"tar.xz\": \"vscode-icons:file-type-zip\",\n  bash: \"vscode-icons:file-type-shell\",\n  binary: \"vscode-icons:file-type-binary\",\n  accdb: \"vscode-icons:file-type-access\",\n  c: \"vscode-icons:file-type-c\",\n  cfg: \"vscode-icons:file-type-ini\",\n  clj: \"vscode-icons:file-type-clojure\",\n  \"compose.yaml\": \"vscode-icons:file-type-docker2\",\n  \"compose.yml\": \"vscode-icons:file-type-docker2\",\n  conf: \"vscode-icons:file-type-ini\",\n  cpp: \"vscode-icons:file-type-cpp\",\n  cjs: \"vscode-icons:file-type-js\",\n  cs: \"vscode-icons:file-type-csharp\",\n  css: \"vscode-icons:file-type-css\",\n  containerfile: \"vscode-icons:file-type-docker\",\n  csv: \"vscode-icons:file-type-excel\",\n  dart: \"vscode-icons:file-type-dartlang\",\n  doc: \"vscode-icons:file-type-word2\",\n  docm: \"vscode-icons:file-type-word\",\n  docx: \"vscode-icons:file-type-word\",\n  dot: \"vscode-icons:file-type-word2\",\n  dotm: \"vscode-icons:file-type-word\",\n  dotx: \"vscode-icons:file-type-word\",\n  docker: \"vscode-icons:file-type-docker\",\n  dockerfile: \"vscode-icons:file-type-docker\",\n  dockerignore: \"vscode-icons:file-type-docker\",\n  \"docker-compose.yaml\": \"vscode-icons:file-type-docker2\",\n  \"docker-compose.yml\": \"vscode-icons:file-type-docker2\",\n  editorconfig: \"vscode-icons:file-type-editorconfig\",\n  env: \"vscode-icons:file-type-dotenv\",\n  erl: \"vscode-icons:file-type-erlang\",\n  eslint: \"vscode-icons:file-type-eslint\",\n  ex: \"vscode-icons:file-type-elixir\",\n  exs: \"vscode-icons:file-type-elixir\",\n  gif: \"vscode-icons:file-type-image\",\n  gitattributes: \"vscode-icons:file-type-git\",\n  gitignore: \"vscode-icons:file-type-git\",\n  go: \"vscode-icons:file-type-go\",\n  gql: \"vscode-icons:file-type-graphql\",\n  graphql: \"vscode-icons:file-type-graphql\",\n  helm: \"vscode-icons:file-type-helm\",\n  hs: \"vscode-icons:file-type-haskell\",\n  htmx: \"vscode-icons:file-type-html\",\n  html: \"vscode-icons:file-type-html\",\n  htm: \"vscode-icons:file-type-html\",\n  ico: \"vscode-icons:file-type-image\",\n  ini: \"vscode-icons:file-type-ini\",\n  java: \"vscode-icons:file-type-java\",\n  jpeg: \"vscode-icons:file-type-image\",\n  jpg: \"vscode-icons:file-type-image\",\n  js: \"vscode-icons:file-type-js\",\n  json: \"vscode-icons:file-type-json\",\n  jsonc: \"vscode-icons:file-type-json\",\n  jsx: \"vscode-icons:file-type-reactjs\",\n  kt: \"vscode-icons:file-type-kotlin\",\n  kts: \"vscode-icons:file-type-kotlin\",\n  less: \"vscode-icons:file-type-less\",\n  lock: \"vscode-icons:file-type-npm\",\n  log: \"vscode-icons:file-type-log\",\n  makefile: \"vscode-icons:file-type-gnu\",\n  lua: \"vscode-icons:file-type-lua\",\n  md: \"vscode-icons:file-type-markdown\",\n  mdx: \"vscode-icons:file-type-mdx\",\n  mdb: \"vscode-icons:file-type-access\",\n  mjs: \"vscode-icons:file-type-js\",\n  nim: \"vscode-icons:file-type-nim\",\n  node: \"vscode-icons:file-type-node\",\n  npm: \"vscode-icons:file-type-npm\",\n  one: \"vscode-icons:file-type-onenote\",\n  otf: \"vscode-icons:file-type-font\",\n  pdf: \"vscode-icons:file-type-pdf2\",\n  php: \"vscode-icons:file-type-php\",\n  pl: \"vscode-icons:file-type-perl\",\n  pm: \"vscode-icons:file-type-perl\",\n  png: \"vscode-icons:file-type-image\",\n  pot: \"vscode-icons:file-type-powerpoint2\",\n  potx: \"vscode-icons:file-type-powerpoint\",\n  pps: \"vscode-icons:file-type-powerpoint2\",\n  ppsx: \"vscode-icons:file-type-powerpoint\",\n  ppt: \"vscode-icons:file-type-powerpoint2\",\n  pptm: \"vscode-icons:file-type-powerpoint\",\n  pptx: \"vscode-icons:file-type-powerpoint\",\n  prettier: \"vscode-icons:file-type-prettier\",\n  prisma: \"vscode-icons:file-type-prisma\",\n  pub: \"vscode-icons:file-type-publisher\",\n  py: \"vscode-icons:file-type-python\",\n  pyw: \"vscode-icons:file-type-python\",\n  r: \"vscode-icons:file-type-r\",\n  rb: \"vscode-icons:file-type-ruby\",\n  rollup: \"vscode-icons:file-type-rollup\",\n  rs: \"vscode-icons:file-type-rust\",\n  sass: \"vscode-icons:file-type-sass\",\n  scss: \"vscode-icons:file-type-scss\",\n  sh: \"vscode-icons:file-type-shell\",\n  sql: \"vscode-icons:file-type-sql\",\n  sqlite: \"vscode-icons:file-type-sqlite\",\n  styl: \"vscode-icons:file-type-stylus\",\n  svelte: \"vscode-icons:file-type-svelte\",\n  svg: \"vscode-icons:file-type-svg\",\n  swift: \"vscode-icons:file-type-swift\",\n  tailwind: \"vscode-icons:file-type-tailwind\",\n  tex: \"vscode-icons:file-type-tex\",\n  templ: \"vscode-icons:file-type-templ\",\n  toml: \"vscode-icons:file-type-toml\",\n  typ: \"material-icon-theme:typst\",\n  ts: \"vscode-icons:file-type-typescript\",\n  tsx: \"vscode-icons:file-type-reactts\",\n  ttf: \"vscode-icons:file-type-font\",\n  txt: \"vscode-icons:file-type-text\",\n  vite: \"vscode-icons:file-type-vite\",\n  vue: \"vscode-icons:file-type-vue\",\n  wasm: \"vscode-icons:file-type-wasm\",\n  webp: \"vscode-icons:file-type-image\",\n  xls: \"vscode-icons:file-type-excel2\",\n  xlsb: \"vscode-icons:file-type-excel2\",\n  xlsm: \"vscode-icons:file-type-excel\",\n  xlsx: \"vscode-icons:file-type-excel\",\n  xltx: \"vscode-icons:file-type-excel\",\n  webpack: \"vscode-icons:file-type-webpack\",\n  woff: \"vscode-icons:file-type-font\",\n  woff2: \"vscode-icons:file-type-font\",\n  xml: \"vscode-icons:file-type-xml\",\n  yaml: \"vscode-icons:file-type-yaml\",\n  yml: \"vscode-icons:file-type-yaml\",\n  zig: \"vscode-icons:file-type-zig\",\n  zsh: \"vscode-icons:file-type-shell\",\n  zip: \"vscode-icons:file-type-zip\",\n};\n",
      "type": "registry:lib",
      "target": "components/f-ui/file-type-icon/vscode-file-type-map.ts"
    }
  ],
  "type": "registry:component"
}