// 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()))
}
}
}