'use client'; import { cn } from '@djangocfg/ui-core/lib'; import { getFileIcon } from './get-file-icon'; import { resolveFolderIcon, type FolderIconOverrides } from './specialFolders'; export type FileIconSize = 12 | 14 | 16 | 18 | 20 | 24 | 28 | 32 | 40 | 48 | 64; export interface FileIconProps { /** File name (with extension) or folder name. */ name: string; /** Render a folder icon instead of a file icon. */ isFolder?: boolean; /** Folder open / closed state. Ignored when `isFolder` is false. */ isExpanded?: boolean; /** Pixel size of the icon. */ size?: FileIconSize; /** * Override or extend the built-in special-folder mapping. Keys are * matched case-insensitively. Only used when `isFolder` is true. */ folderOverrides?: FolderIconOverrides; /** * Accessible label. When omitted the icon is decorative (`aria-hidden`) — * correct when it sits next to a visible file name. Pass a string to * expose the icon to assistive technology. */ label?: string; className?: string; } /** * VSCode-style file icon. * * - Folders render Lucide `Folder` / `FolderOpen` (warning-token tint). * - Files render rich, colourful SVGs vendored from `material-file-icons` * (MIT). Resolution is synchronous — no runtime dependency, no async load. * * The icon SVG data is a static module, so it bundles into the `FileIcon` * chunk and is only fetched by consumers that actually mount this component. */ export function FileIcon({ name, isFolder = false, isExpanded = false, size = 16, folderOverrides, label, className, }: FileIconProps) { // Either a labelled image, or fully hidden from assistive tech (the default, // since the icon usually sits beside a visible file name). const a11y = label === undefined ? ({ 'aria-hidden': true } as const) : ({ role: 'img', 'aria-label': label } as const); if (isFolder) { const Icon = resolveFolderIcon({ name, isExpanded, overrides: folderOverrides, }); return ( ); } // Vendored static data — `getFileIcon` always returns a definition. const svg = getFileIcon(name).svg; return ( ); } export default FileIcon;