use leptos::prelude::*; #[derive(Clone, Copy, PartialEq, Debug)] // Several variants are used from later milestones (context menu icons). #[allow(dead_code)] pub enum IconName { Folder, File, Image, Video, Audio, Text, Code, Archive, Pdf, Grid, List, Refresh, Upload, FolderPlus, Download, Pencil, Move, Copy, Share, Info, Trash, } /// Pick the icon for a file name based on its extension. pub fn icon_for(name: &str, is_dir: bool) -> IconName { if is_dir { return IconName::Folder; } let ext = name.rsplit('.').next().unwrap_or("").to_lowercase(); match ext.as_str() { "png" | "jpg" | "jpeg" | "gif" | "webp" | "svg" | "bmp" | "ico" | "avif" => IconName::Image, "mp4" | "webm" | "mkv" | "mov" | "avi" => IconName::Video, "mp3" | "wav" | "ogg" | "flac" | "m4a" | "opus" => IconName::Audio, "pdf" => IconName::Pdf, "zip" | "tar" | "gz" | "tgz" | "zst" | "bz2" | "xz" | "7z" | "rar" => IconName::Archive, "rs" | "js" | "ts" | "tsx" | "jsx" | "py" | "rb" | "go" | "c" | "cpp" | "h" | "hpp" | "json" | "toml" | "yaml" | "yml" | "sh" | "html" | "css" | "wasm" | "sql" => { IconName::Code } "txt" | "md" | "log" | "csv" | "ini" | "conf" | "xml" => IconName::Text, _ => IconName::File, } } fn icon_d(name: IconName) -> &'static str { match name { IconName::Folder => { "M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" } IconName::File => "M6 2h8l5 5v13a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2z M13 2v6h6", IconName::Image => { "M3 5h18v14H3z M10 10a1.5 1.5 0 1 1-3 0a1.5 1.5 0 0 1 3 0z M21 15l-5-5-9 9" } IconName::Video => "M3 5h18v14H3z M10 9l5 3-5 3z", IconName::Audio => { "M9 18V6l10-2v10 M9 18a2.5 2.5 0 1 1-5 0 2.5 2.5 0 0 1 5 0z M19 15a2.5 2.5 0 1 1-5 0 2.5 2.5 0 0 1 5 0z" } IconName::Text => "M5 3h14v18H5z M9 8h6 M9 12h6 M9 16h4", IconName::Code => "M8 8l-4 4 4 4 M16 8l4 4-4 4", IconName::Archive => "M4 4h16v16H4z M12 4v2 M12 8v2 M12 12v2 M9 16h6v4H9z", IconName::Pdf => { "M6 2h8l5 5v13a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2z M13 2v6h6 M8 13h8 M8 17h8" } IconName::Grid => "M4 4h7v7H4z M13 4h7v7h-7z M4 13h7v7H4z M13 13h7v7h-7z", IconName::List => "M4 6h2 M9 6h11 M4 12h2 M9 12h11 M4 18h2 M9 18h11", IconName::Refresh => "M21 12a9 9 0 1 1-3-6.7 M21 3v6h-6", IconName::Upload => "M12 16V4 M7 9l5-5 5 5 M4 20h16", IconName::FolderPlus => { "M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z M12 11v6 M9 14h6" } IconName::Download => "M12 4v12 M7 11l5 5 5-5 M4 20h16", IconName::Pencil => "M4 20l1-4L16 5l3 3L8 19z M13 8l3 3", IconName::Move => "M20 7H6 M9 4L6 7l3 3 M4 17h14 M15 14l3 3-3 3", IconName::Copy => "M8 8h12v12H8z M4 16V4h12", IconName::Share => "M4 13v6a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1v-6 M12 3v11 M8 7l4-4 4 4", IconName::Info => "M12 3a9 9 0 1 0 .01 0z M12 11v5 M12 8h.01", IconName::Trash => "M4 7h16 M9 7V4h6v3 M6 7l1 13h10l1-13 M10 11v6 M14 11v6", } } fn icon_class(name: IconName) -> &'static str { match name { IconName::Folder | IconName::FolderPlus => "ic-folder", _ => "ic-muted", } } #[component] pub fn Icon(name: IconName, class: Option) -> impl IntoView { let mut cls = String::from("icon "); cls.push_str(icon_class(name)); if let Some(extra) = class { cls.push(' '); cls.push_str(&extra); } view! { } }