| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | use maud::{Markup, PreEscaped, html}; |
| 12 | |
| 13 | |
| 14 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
| 15 | pub enum Icon { |
| 16 | PanelLeft, |
| 17 | Folder, |
| 18 | File, |
| 19 | GitBranch, |
| 20 | Issue, |
| 21 | GitPull, |
| 22 | History, |
| 23 | ChevronDown, |
| 24 | Search, |
| 25 | Copy, |
| 26 | Plus, |
| 27 | Box, |
| 28 | Link, |
| 29 | User, |
| 30 | Settings, |
| 31 | LogOut, |
| 32 | Upload, |
| 33 | Dashboard, |
| 34 | Compass, |
| 35 | MapPin, |
| 36 | Mail, |
| 37 | Check, |
| 38 | X, |
| 39 | Scale, |
| 40 | Globe, |
| 41 | Download, |
| 42 | Mirror, |
| 43 | GitFork, |
| 44 | Bookmark, |
| 45 | Users, |
| 46 | Bell, |
| 47 | Github, |
| 48 | Mastodon, |
| 49 | } |
| 50 | |
| 51 | impl Icon { |
| 52 | |
| 53 | fn brand(self) -> bool { |
| 54 | matches!(self, Icon::Github | Icon::Mastodon) |
| 55 | } |
| 56 | |
| 57 | |
| 58 | fn geometry(self) -> &'static str { |
| 59 | match self { |
| 60 | Icon::PanelLeft => { |
| 61 | r#"<rect width="18" height="18" x="3" y="3" rx="2"/><path d="M9 3v18"/>"# |
| 62 | } |
| 63 | Icon::Folder => { |
| 64 | r#"<path d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z"/>"# |
| 65 | } |
| 66 | Icon::File => { |
| 67 | r#"<path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z"/><path d="M14 2v5a1 1 0 0 0 1 1h5"/>"# |
| 68 | } |
| 69 | Icon::GitBranch => { |
| 70 | r#"<path d="M15 6a9 9 0 0 0-9 9V3"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/>"# |
| 71 | } |
| 72 | Icon::Issue => r#"<circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="1"/>"#, |
| 73 | Icon::GitPull => { |
| 74 | r#"<circle cx="18" cy="18" r="3"/><circle cx="6" cy="6" r="3"/><path d="M13 6h3a2 2 0 0 1 2 2v7"/><line x1="6" x2="6" y1="9" y2="21"/>"# |
| 75 | } |
| 76 | Icon::History => { |
| 77 | r#"<path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/><path d="M3 3v5h5"/><path d="M12 7v5l4 2"/>"# |
| 78 | } |
| 79 | Icon::ChevronDown => r#"<path d="m6 9 6 6 6-6"/>"#, |
| 80 | Icon::Plus => r#"<path d="M5 12h14"/><path d="M12 5v14"/>"#, |
| 81 | Icon::Search => r#"<path d="m21 21-4.34-4.34"/><circle cx="11" cy="11" r="8"/>"#, |
| 82 | Icon::Copy => { |
| 83 | r#"<rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/>"# |
| 84 | } |
| 85 | Icon::Box => { |
| 86 | r#"<path d="M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z"/><path d="m3.3 7 8.7 5 8.7-5"/><path d="M12 22V12"/>"# |
| 87 | } |
| 88 | Icon::Link => { |
| 89 | r#"<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>"# |
| 90 | } |
| 91 | Icon::User => { |
| 92 | r#"<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>"# |
| 93 | } |
| 94 | Icon::Settings => { |
| 95 | r#"<path d="M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915"/><circle cx="12" cy="12" r="3"/>"# |
| 96 | } |
| 97 | Icon::LogOut => { |
| 98 | r#"<path d="m16 17 5-5-5-5"/><path d="M21 12H9"/><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/>"# |
| 99 | } |
| 100 | Icon::Upload => { |
| 101 | r#"<path d="M12 3v12"/><path d="m17 8-5-5-5 5"/><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>"# |
| 102 | } |
| 103 | Icon::Dashboard => { |
| 104 | r#"<rect width="7" height="9" x="3" y="3" rx="1"/><rect width="7" height="5" x="14" y="3" rx="1"/><rect width="7" height="9" x="14" y="12" rx="1"/><rect width="7" height="5" x="3" y="16" rx="1"/>"# |
| 105 | } |
| 106 | Icon::Compass => { |
| 107 | r#"<circle cx="12" cy="12" r="10"/><path d="m16.24 7.76-1.804 5.411a2 2 0 0 1-1.265 1.265L7.76 16.24l1.804-5.411a2 2 0 0 1 1.265-1.265z"/>"# |
| 108 | } |
| 109 | Icon::MapPin => { |
| 110 | r#"<path d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0"/><circle cx="12" cy="10" r="3"/>"# |
| 111 | } |
| 112 | Icon::Mail => { |
| 113 | r#"<rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/>"# |
| 114 | } |
| 115 | Icon::Check => r#"<path d="M20 6 9 17l-5-5"/>"#, |
| 116 | Icon::X => r#"<path d="M18 6 6 18"/><path d="m6 6 12 12"/>"#, |
| 117 | Icon::Scale => { |
| 118 | r#"<path d="m16 16 3-8 3 8c-.87.65-1.92 1-3 1s-2.13-.35-3-1Z"/><path d="m2 16 3-8 3 8c-.87.65-1.92 1-3 1s-2.13-.35-3-1Z"/><path d="M7 21h10"/><path d="M12 3v18"/><path d="M3 7h2c2 0 5-1 7-2 2 1 5 2 7 2h2"/>"# |
| 119 | } |
| 120 | Icon::Globe => { |
| 121 | r#"<circle cx="12" cy="12" r="10"/><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20"/><path d="M2 12h20"/>"# |
| 122 | } |
| 123 | Icon::Download => { |
| 124 | r#"<path d="M12 15V3"/><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="m7 10 5 5 5-5"/>"# |
| 125 | } |
| 126 | |
| 127 | Icon::Mirror => { |
| 128 | r#"<path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/><path d="M8 16H3v5"/>"# |
| 129 | } |
| 130 | |
| 131 | Icon::GitFork => { |
| 132 | r#"<circle cx="12" cy="18" r="3"/><circle cx="6" cy="6" r="3"/><circle cx="18" cy="6" r="3"/><path d="M18 9v2c0 .6-.4 1-1 1H7c-.6 0-1-.4-1-1V9"/><path d="M12 12v3"/>"# |
| 133 | } |
| 134 | |
| 135 | Icon::Bookmark => r#"<path d="m19 21-7-4-7 4V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v16z"/>"#, |
| 136 | |
| 137 | Icon::Users => { |
| 138 | r#"<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/>"# |
| 139 | } |
| 140 | |
| 141 | Icon::Bell => { |
| 142 | r#"<path d="M10.268 21a2 2 0 0 0 3.464 0"/><path d="M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326"/>"# |
| 143 | } |
| 144 | Icon::Github => { |
| 145 | r#"<path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/>"# |
| 146 | } |
| 147 | Icon::Mastodon => { |
| 148 | r#"<path d="M23.268 5.313c-.35-2.578-2.617-4.61-5.304-5.004C17.51.242 15.792 0 11.813 0h-.03c-3.98 0-4.835.242-5.288.309C3.882.692 1.496 2.518.917 5.127.64 6.412.61 7.837.661 9.143c.074 1.874.088 3.745.26 5.611.118 1.24.325 2.47.62 3.68.55 2.237 2.777 4.098 4.96 4.857 2.336.792 4.849.923 7.256.38.265-.061.527-.132.786-.213.585-.184 1.27-.39 1.774-.753a.057.057 0 0 0 .023-.043v-1.809a.052.052 0 0 0-.02-.041.053.053 0 0 0-.046-.01 20.282 20.282 0 0 1-4.709.545c-2.73 0-3.463-1.284-3.674-1.818a5.593 5.593 0 0 1-.319-1.433.053.053 0 0 1 .066-.054c1.517.363 3.072.546 4.632.546.376 0 .75 0 1.125-.01 1.57-.044 3.224-.124 4.768-.422.038-.008.077-.015.11-.024 2.435-.464 4.753-1.92 4.989-5.604.008-.145.03-1.52.03-1.67.002-.512.167-3.63-.024-5.545zm-3.748 9.195h-2.561V8.29c0-1.309-.55-1.976-1.67-1.976-1.23 0-1.846.79-1.846 2.35v3.403h-2.546V8.663c0-1.56-.617-2.35-1.848-2.35-1.112 0-1.668.668-1.67 1.977v6.218H4.822V8.102c0-1.31.337-2.35 1.011-3.12.696-.77 1.608-1.164 2.74-1.164 1.311 0 2.302.5 2.962 1.498l.638 1.06.638-1.06c.66-.999 1.65-1.498 2.96-1.498 1.13 0 2.043.395 2.74 1.164.675.77 1.012 1.81 1.012 3.12z"/>"# |
| 149 | } |
| 150 | } |
| 151 | } |
| 152 | } |
| 153 | |
| 154 | |
| 155 | #[must_use] |
| 156 | pub fn icon(name: Icon) -> Markup { |
| 157 | let brand = name.brand(); |
| 158 | html! { |
| 159 | svg class="icon" viewBox="0 0 24 24" width="1em" height="1em" |
| 160 | fill=(if brand { "currentColor" } else { "none" }) |
| 161 | stroke=(if brand { "none" } else { "currentColor" }) |
| 162 | stroke-width="2" stroke-linecap="round" stroke-linejoin="round" |
| 163 | aria-hidden="true" focusable="false" { |
| 164 | (PreEscaped(name.geometry())) |
| 165 | } |
| 166 | } |
| 167 | } |