FileIcon
A file's icon by its extension, written on it and coloured by its kind: document, sheet, PDF, image, code and more.
Demo
- Q3 report.xlsxsheet
- Contract (signed).pdfpdf
- team-photo.JPGimage
- pitch.keyslides
- notes.mdtext
- main.qwecode
- backup.tar.gzarchive
- voice memo.m4aaudio
- intro.mp4video
- READMEother
- proposal.docxdocument
Get it
It needs theme.qwe, as every component does; or take the whole kit, quillo-ui.qwe. Each component brings its own styles to the pages that show it.
$ curl -O https://quillolang.org/components/ui/theme.qwe$ curl -O https://quillolang.org/components/ui/file_icon.qwemain.qwe
import ui/theme.qwe use theme_cssuse ui/file_icon.qweroute GET / = <html><head><style>{theme_css}</style></head><body class="ui-root">...</body></html>Example
The code of the preview above.
demos/file_icon.qwe
let file_icon_demo_files = ["Q3 report.xlsx", "Contract (signed).pdf", "team-photo.JPG", "pitch.key", "notes.md", "main.qwe", "backup.tar.gz", "voice memo.m4a", "intro.mp4", "README", "proposal.docx"]view FileIconDemo() = <div.demo-stack> <div.demo-row id="file-icon-demo-sizes"> <FileIcon ext="pdf" size="sm"/> <FileIcon ext="pdf"/> <FileIcon ext="pdf" size="lg"/> <FileIcon ext="pdf" size="xl"/> </div> <ul id="file-icon-demo-list" style="display: grid; gap: 6px; margin: 0; padding: 0; list-style: none"> {for f in file_icon_demo_files => <li style="display: flex; align-items: center; gap: 10px"> <FileIcon name={f} size="sm" label=""/> <span>{f}</span> <span style="color: var(--ui-muted); font-size: 13px">{file_icon_kind(file_icon_ext(f))}</span> </li>} </ul> </div>Source
ui/file_icon.qwe
// FileIcon: a file's icon by its extension, with the extension written on it and// a colour for its kind, so a list of files reads at a glance.//// <FileIcon ext="pdf"/>// <FileIcon name="Q3 report.xlsx" size="lg"/>// <li><FileIcon name={f.name} size="sm"/> {f.name}</li>//// ext: the extension ("pdf", "XLSX", with or without the dot); or name, a file// name it is taken from ("notes.final.md" gives "md"). Neither, or no extension:// a plain file. size: "sm" (24px tall), "md" (36px, default), "lg" (52px) or// "xl" (72px). label: what screen readers say ("PDF file" by default); hidden// from them when label is "".// Kinds, each its own colour: document (doc, docx, odt, rtf, pages), sheet (xls,// xlsx, csv, ods, numbers), slides (ppt, pptx, key, odp), pdf, image (png, jpg,// jpeg, gif, svg, webp, heic, bmp, tiff), video (mp4, mov, webm, mkv, avi), audio// (mp3, wav, flac, aac, ogg, m4a), archive (zip, tar, gz, rar, 7z, dmg), code (js,// ts, py, rs, go, rb, java, c, h, cpp, cs, php, swift, kt, qwe, html, css, json,// yaml, yml, toml, xml, sh, sql), text (txt, md, log) and other.// file_icon_kind(ext) gives the kind's name, to colour something else by it.import ui/theme.qwe use ui_clslet file_icon_css = css`.ui-file-icon { display: inline-block; flex: none; width: auto; height: 36px; vertical-align: middle; --c: var(--ui-muted); }.ui-file-icon-sm { height: 24px; }.ui-file-icon-lg { height: 52px; }.ui-file-icon-xl { height: 72px; }.ui-file-icon-sheet { --c: #18794e; } .ui-file-icon-document { --c: #0b6bcb; } .ui-file-icon-slides { --c: #d9480f; }.ui-file-icon-pdf { --c: #c62a2f; } .ui-file-icon-image { --c: #7c3aed; } .ui-file-icon-video { --c: #be185d; }.ui-file-icon-audio { --c: #0e7490; } .ui-file-icon-archive { --c: #8a6d1a; } .ui-file-icon-code { --c: #2f6b3a; }.ui-file-icon-text { --c: #5e5c6e; }.ui-file-icon-page { fill: var(--ui-surface); stroke: var(--ui-strong); stroke-width: 1.5; }.ui-file-icon-fold { fill: var(--ui-subtle); stroke: var(--ui-strong); stroke-width: 1.5; stroke-linejoin: round; }.ui-file-icon-tag { fill: var(--c); }.ui-file-icon-ext { fill: #fff; font: 700 9px/1 var(--ui-font); letter-spacing: .03em; text-anchor: middle; }.ui-file-icon-long .ui-file-icon-ext { font-size: 7.5px; }`// The extension of a file name, lower-case, or "" when it has none.fn file_icon_ext(name: str) -> str { let base = last(split(name, "/")) ?? "" let parts = split(base, ".") len(parts) < 2 || parts[-1] == "" ? "" : lower(parts[-1])}// The kind of file an extension names: "document", "sheet", "slides", "pdf", "image",// "video", "audio", "archive", "code", "text" or "other".fn file_icon_kind(ext: str) -> str = match lower(ext) { "doc" | "docx" | "odt" | "rtf" | "pages" => "document" "xls" | "xlsx" | "csv" | "ods" | "numbers" => "sheet" "ppt" | "pptx" | "key" | "odp" => "slides" "pdf" => "pdf" "png" | "jpg" | "jpeg" | "gif" | "svg" | "webp" | "heic" | "bmp" | "tiff" => "image" "mp4" | "mov" | "webm" | "mkv" | "avi" => "video" "mp3" | "wav" | "flac" | "aac" | "ogg" | "m4a" => "audio" "zip" | "tar" | "gz" | "rar" | "7z" | "dmg" => "archive" "js" | "ts" | "py" | "rs" | "go" | "rb" | "java" | "c" | "h" | "cpp" | "cs" | "php" | "swift" | "kt" | "qwe" | "html" | "css" | "json" | "yaml" | "yml" | "toml" | "xml" | "sh" | "sql" => "code" "txt" | "md" | "log" => "text" _ => "other" }view FileIcon(ext: str? = null, name: str? = null, size: str = "md", label: str? = null, class: str? = null) { style global file_icon_css let e = lower(replace(ext ?? (name != null ? file_icon_ext(name) : ""), ".", "")) let kind = e == "" ? "other" : file_icon_kind(e) let shown = upper(len(e) > 5 ? slice(e, 0, 5) : e) let said = label ?? (e == "" ? "File" : `${shown} file`) <svg class={ui_cls(["ui-file-icon", size != "md" && `ui-file-icon-${size}`, kind != "other" && `ui-file-icon-${kind}`, len(shown) > 3 && "ui-file-icon-long", class])} viewBox="0 0 32 40" data-ext={e} data-kind={kind} role={said != "" ? "img" : null} aria-label={said != "" ? said : null} aria-hidden={said == "" ? "true" : null}> <path.ui-file-icon-page d="M5 1h15l8 8v29a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1Z"/> <path.ui-file-icon-fold d="M20 1v8h8"/> {shown != "" && [ <rect.ui-file-icon-tag x="1" y="22" width="26" height="12" rx="2"/>, <text.ui-file-icon-ext x="14" y="31">{shown}</text>, ]} </svg>}Related
IconEighty common icons by name, drawn inline as SVG in the text's colour, in five sizes or any pixel size.7 views · 6 downloadsIconGridEvery icon of the kit with its name in a grid, narrowed as you type, each one a click away from its name.6 views · 7 downloadsPdfViewerA PDF in the page with the browser's own viewer, a bar with its name, open and download links, and a fallback.6 views · 7 downloadsFilePreviewA look at a file before opening it: an image, a PDF in an object, the start of a text file, a player, or an icon, with name, size and a download link.5 views · 7 downloadsAudioPlayerAn audio clip with play, a seek bar that says the time, and a button cycling through playback speeds.6 views · 7 downloadsCameraCaptureTakes a photo with the camera into a hidden input as a data URL, with retake, and says so when there is no camera.6 views · 6 downloads
Thread
Thread 0 posts
On FileIcon: questions, tips, corrections, and code that uses it.
No posts yet. The first one opens the thread.