// This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. //! Inline SVG icons. //! //! Vendored from [Lucide](https://lucide.dev) (ISC) for UI glyphs and //! [Simple Icons](https://simpleicons.org) (CC0) for brands, inlined so no page //! makes a network request. Icons inherit `currentColor` and size to `1em`. use maud::{Markup, PreEscaped, html}; /// A vendored icon. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Icon { PanelLeft, Folder, File, GitBranch, Issue, GitPull, History, ChevronDown, Search, Copy, Plus, Box, Link, User, Settings, LogOut, Upload, Dashboard, Compass, MapPin, Mail, Check, X, Scale, Globe, Download, Mirror, GitFork, Bookmark, Users, Bell, Github, Mastodon, } impl Icon { /// Whether the icon is a filled brand glyph rather than a stroked Lucide one. fn brand(self) -> bool { matches!(self, Icon::Github | Icon::Mastodon) } /// The inner SVG geometry. fn geometry(self) -> &'static str { match self { Icon::PanelLeft => { r#""# } Icon::Folder => { r#""# } Icon::File => { r#""# } Icon::GitBranch => { r#""# } Icon::Issue => r#""#, Icon::GitPull => { r#""# } Icon::History => { r#""# } Icon::ChevronDown => r#""#, Icon::Plus => r#""#, Icon::Search => r#""#, Icon::Copy => { r#""# } Icon::Box => { r#""# } Icon::Link => { r#""# } Icon::User => { r#""# } Icon::Settings => { r#""# } Icon::LogOut => { r#""# } Icon::Upload => { r#""# } Icon::Dashboard => { r#""# } Icon::Compass => { r#""# } Icon::MapPin => { r#""# } Icon::Mail => { r#""# } Icon::Check => r#""#, Icon::X => r#""#, Icon::Scale => { r#""# } Icon::Globe => { r#""# } Icon::Download => { r#""# } // Lucide "refresh-cw": circular arrows, for a mirror (kept in sync). Icon::Mirror => { r#""# } // Lucide "git-fork": two branches diverging from a commit. Icon::GitFork => { r#""# } // Lucide "bookmark". Icon::Bookmark => r#""#, // Lucide "users": follower/following counts. Icon::Users => { r#""# } // Lucide "bell": notifications. Icon::Bell => { r#""# } Icon::Github => { r#""# } Icon::Mastodon => { r#""# } } } } /// Render an icon inheriting `currentColor` and sized to `1em`. #[must_use] pub fn icon(name: Icon) -> Markup { let brand = name.brand(); html! { svg class="icon" viewBox="0 0 24 24" width="1em" height="1em" fill=(if brand { "currentColor" } else { "none" }) stroke=(if brand { "none" } else { "currentColor" }) stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false" { (PreEscaped(name.geometry())) } } }