{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"file-icon","title":"File Icon","description":"A coloured icon for each kind of file — document, spreadsheet, presentation, PDF, image, video, music, archive or a plain file — sized like a Lucide icon in attachments and lists.","dependencies":["cn"],"files":[{"path":"components/ui/file-icon.tsx","content":"import * as React from \"react\"\nimport { cn } from \"cn\"\n\ntype FileIconType =\n  | \"file\"\n  | \"archive\"\n  | \"document\"\n  | \"spreadsheet\"\n  | \"presentation\"\n  | \"pdf\"\n  | \"video\"\n  | \"music\"\n  | \"image\"\n\nconst PAGE =\n  \"M3.9 3.36C3.9 2.167 4.867 1.2 6.06 1.2H14.266C14.544 1.2 14.812 1.308 15.013 1.5L19.767 6.055C19.98 6.259 20.1 6.54 20.1 6.835V20.64C20.1 21.833 19.133 22.8 17.94 22.8H6.06C4.867 22.8 3.9 21.833 3.9 20.64V3.36Z\"\nconst FOLD = \"M14.7 2.28L19.02 6.6H14.7V2.28Z\"\n\nconst icons: Record<\n  FileIconType,\n  {\n    stops: [string, string, string]\n    middle?: number\n    fold?: string\n    mark: React.ReactNode\n  }\n> = {\n  file: {\n    stops: [\"#D3D2D2\", \"#BDBDBD\", \"#E5E5E5\"],\n    fold: \"#9F9F9F\",\n    mark: null,\n  },\n  archive: {\n    stops: [\"#D3D2D2\", \"#BDBDBD\", \"#E5E5E5\"],\n    mark: (\n      <path\n        fill=\"#fff\"\n        d=\"M11.351 14.052H12.863V14.7H11.351V14.052Z M11.352 11.46H12.864V12.108H11.352V11.46Z M11.351 9.3H12.863V9.948H11.351V9.3Z M12.755 15.996H11.243C11.243 17.022 10.487 18.048 10.487 18.732C10.487 19.488 11.163 20.1 11.999 20.1C12.835 20.1 13.511 19.488 13.511 18.732C13.511 18.048 12.755 17.022 12.755 15.996ZM11.999 19.416C11.581 19.416 11.243 19.11 11.243 18.732C11.243 18.354 11.581 18.048 11.999 18.048C12.417 18.048 12.755 18.354 12.755 18.732C12.755 19.11 12.417 19.416 11.999 19.416Z\"\n      />\n    ),\n  },\n  document: {\n    stops: [\"#73C4FE\", \"#42B0FF\", \"#9AD4FE\"],\n    fold: \"#C1D9FF\",\n    mark: (\n      <path\n        fill=\"#D6E5FD\"\n        d=\"M7.2 12.6C7.2 12.269 7.469 12 7.8 12H16.2C16.531 12 16.8 12.269 16.8 12.6C16.8 12.931 16.531 13.2 16.2 13.2H7.8C7.469 13.2 7.2 12.931 7.2 12.6Z M7.2 15.6C7.2 15.269 7.469 15 7.8 15H16.2C16.531 15 16.8 15.269 16.8 15.6C16.8 15.931 16.531 16.2 16.2 16.2H7.8C7.469 16.2 7.2 15.931 7.2 15.6Z M7.2 18.6C7.2 18.269 7.469 18 7.8 18H12.6C12.931 18 13.2 18.269 13.2 18.6C13.2 18.931 12.931 19.2 12.6 19.2H7.8C7.469 19.2 7.2 18.931 7.2 18.6Z\"\n      />\n    ),\n  },\n  spreadsheet: {\n    stops: [\"#4AEC8B\", \"#00C950\", \"#3EF386\"],\n    fold: \"#73F9A8\",\n    mark: (\n      <path\n        stroke=\"#B9FFD4\"\n        strokeWidth={0.9}\n        d=\"M12 12.6H7.8C7.137 12.6 6.6 13.137 6.6 13.8V16.2M12 12.6H16.2C16.863 12.6 17.4 13.137 17.4 13.8V16.2M12 12.6V19.8M12 19.8H16.2C16.863 19.8 17.4 19.263 17.4 18.6V16.2M12 19.8H7.8C7.137 19.8 6.6 19.263 6.6 18.6V16.2M6.6 16.2H17.4\"\n      />\n    ),\n  },\n  presentation: {\n    stops: [\"#FFBE70\", \"#FE9110\", \"#FCC685\"],\n    fold: \"#FDD5A4\",\n    mark: (\n      <g stroke=\"#FFEAD1\" strokeWidth={0.9}>\n        <path d=\"M6.6 14.8C6.6 14.137 7.137 13.6 7.8 13.6H16.2C16.863 13.6 17.4 14.137 17.4 14.8V18.6C17.4 19.263 16.863 19.8 16.2 19.8H7.8C7.137 19.8 6.6 19.263 6.6 18.6L6.6 14.8Z\" />\n        <path strokeLinecap=\"round\" d=\"M8 11.5h8\" />\n      </g>\n    ),\n  },\n  pdf: {\n    stops: [\"#FFA86B\", \"#FF6900\", \"#FEA363\"],\n    fold: \"#FFB480\",\n    mark: (\n      <path\n        fill=\"#FFEBDC\"\n        d=\"M6.789 18.3V13.774H8.223C8.534 13.774 8.808 13.833 9.046 13.952C9.284 14.071 9.469 14.237 9.6 14.45C9.732 14.662 9.798 14.915 9.798 15.208C9.798 15.497 9.732 15.748 9.6 15.96C9.469 16.173 9.284 16.339 9.046 16.458C8.808 16.572 8.534 16.63 8.223 16.63H7.58V18.3H6.789ZM7.58 15.909H8.141C8.425 15.909 8.636 15.85 8.772 15.731C8.912 15.608 8.982 15.433 8.982 15.208C8.982 14.974 8.912 14.798 8.772 14.679C8.636 14.56 8.425 14.501 8.141 14.501H7.58V15.909Z M10.573 18.3V13.774H11.702C12.114 13.774 12.469 13.863 12.766 14.041C13.068 14.216 13.298 14.473 13.455 14.813C13.616 15.149 13.697 15.559 13.697 16.043C13.697 16.528 13.616 16.938 13.455 17.274C13.298 17.609 13.068 17.864 12.766 18.039C12.469 18.213 12.114 18.3 11.702 18.3H10.573ZM11.357 17.573H11.702C12.08 17.573 12.371 17.446 12.575 17.191C12.779 16.936 12.881 16.553 12.881 16.043C12.881 15.529 12.779 15.144 12.575 14.889C12.371 14.63 12.08 14.501 11.702 14.501H11.357V17.573Z M14.523 18.3V13.774H17.379V14.488H14.829L15.314 14.029V16.107L14.829 15.731H17.265V16.439H14.829L15.314 16.069V18.3H14.523Z\"\n      />\n    ),\n  },\n  video: {\n    stops: [\"#21DCFF\", \"#00B8DB\", \"#67E7FF\"],\n    fold: \"#80DBED\",\n    mark: (\n      <path\n        fill=\"#AAE8F5\"\n        d=\"M15.528 15.091L10.229 18.624C10.114 18.7 9.958 18.669 9.882 18.554C9.854 18.513 9.84 18.465 9.84 18.416V11.35C9.84 11.212 9.952 11.1 10.09 11.1C10.139 11.1 10.188 11.115 10.229 11.142L15.528 14.675C15.643 14.751 15.674 14.907 15.597 15.021C15.579 15.049 15.555 15.073 15.528 15.091Z\"\n      />\n    ),\n  },\n  music: {\n    stops: [\"#EF7CFF\", \"#E12AFB\", \"#F39BFF\"],\n    fold: \"#F094FD\",\n    mark: (\n      <path\n        fill=\"#F8C8FF\"\n        fillRule=\"evenodd\"\n        clipRule=\"evenodd\"\n        d=\"M14.083 13.402C14.216 13.402 14.323 13.295 14.323 13.162V12.777C14.323 12.644 14.216 12.537 14.083 12.537H12.833C12.696 12.537 12.576 12.63 12.543 12.763L12 14.913C11.909 14.847 11.809 14.795 11.7 14.757C11.591 14.72 11.473 14.7 11.347 14.7C11.048 14.7 10.794 14.806 10.584 15.016C10.374 15.226 10.269 15.48 10.269 15.779C10.269 16.077 10.374 16.331 10.584 16.542C10.794 16.752 11.048 16.857 11.347 16.857C11.645 16.857 11.879 16.765 12.114 16.542C12.351 16.315 12.464 15.779 12.464 15.779L13.021 13.448C13.028 13.421 13.052 13.402 13.08 13.402H14.083ZM12 10.38C12.592 10.38 13.151 10.493 13.678 10.718C14.204 10.944 14.662 11.252 15.052 11.645C15.441 12.037 15.75 12.495 15.978 13.019C16.206 13.543 16.32 14.103 16.32 14.7C16.32 15.293 16.206 15.852 15.978 16.378C15.75 16.905 15.441 17.363 15.052 17.753C14.662 18.142 14.204 18.451 13.678 18.679C13.151 18.907 12.592 19.02 12 19.02C11.402 19.02 10.842 18.907 10.318 18.679C9.794 18.451 9.336 18.142 8.944 17.753C8.552 17.363 8.243 16.905 8.018 16.378C7.792 15.852 7.68 15.293 7.68 14.7C7.68 14.103 7.792 13.543 8.018 13.019C8.243 12.495 8.552 12.037 8.944 11.645C9.336 11.252 9.794 10.944 10.318 10.718C10.842 10.493 11.402 10.38 12 10.38Z\"\n      />\n    ),\n  },\n  image: {\n    stops: [\"#6AE3FF\", \"#01C2ED\", \"#7EE7FF\"],\n    middle: 0.527,\n    mark: (\n      <g fill=\"#BEF3FF\">\n        <path d=\"M7.425 11.266L1.556 17V24.5H23.5L9.65 11.198C9.035 10.557 8 10.589 7.425 11.266Z\" />\n        <circle cx={15} cy={10} r={2} />\n      </g>\n    ),\n  },\n}\n\nfunction FileIcon({\n  type = \"file\",\n  title,\n  className,\n  ...props\n}: Omit<React.ComponentProps<\"svg\">, \"children\" | \"type\"> & {\n  /** The kind of file the icon stands for. */\n  type?: FileIconType\n  /** Accessible name; omitted = decorative (`aria-hidden`). */\n  title?: string\n}) {\n  const id = React.useId().replace(/[^\\w-]/g, \"\")\n  const icon = icons[type]\n  const labelled = Boolean(\n    title || props[\"aria-label\"] || props[\"aria-labelledby\"]\n  )\n\n  return (\n    <svg\n      data-slot=\"file-icon\"\n      data-type={type}\n      xmlns=\"http://www.w3.org/2000/svg\"\n      viewBox=\"0 0 24 24\"\n      width={24}\n      height={24}\n      fill=\"none\"\n      role={labelled ? \"img\" : undefined}\n      aria-hidden={labelled ? undefined : true}\n      className={cn(\"shrink-0\", className)}\n      {...props}\n    >\n      {title ? <title>{title}</title> : null}\n      <defs>\n        <radialGradient\n          id={`${id}-page`}\n          cx={0}\n          cy={0}\n          r={1}\n          gradientUnits=\"userSpaceOnUse\"\n          gradientTransform=\"matrix(0 22 -21.347 0 9.895 1)\"\n        >\n          <stop offset={0.004} stopColor={icon.stops[0]} />\n          <stop offset={icon.middle ?? 0.612} stopColor={icon.stops[1]} />\n          <stop offset={1} stopColor={icon.stops[2]} />\n        </radialGradient>\n        <clipPath id={`${id}-clip`}>\n          <path d={PAGE} />\n        </clipPath>\n      </defs>\n      <path fill={`url(#${id}-page)`} d={PAGE} />\n      <path\n        d={PAGE}\n        fill=\"none\"\n        strokeWidth={1}\n        vectorEffect=\"non-scaling-stroke\"\n        className=\"stroke-control-border\"\n        clipPath={`url(#${id}-clip)`}\n      />\n      {icon.fold ? <path fill={icon.fold} d={FOLD} /> : null}\n      <g clipPath={`url(#${id}-clip)`}>{icon.mark}</g>\n    </svg>\n  )\n}\n\nexport { FileIcon, type FileIconType }\n","type":"registry:ui"}],"cssVars":{"theme":{"color-control-border":"var(--control-border)"},"light":{"control-border":"oklch(0.145 0 0 / 10%)"},"dark":{"control-border":"oklch(1 0 0 / 10%)"}},"categories":["content"],"type":"registry:ui"}