collin/anvil · 0c9a5673
ui: button groups, plain repo nav links, and profile dropdown
Collin Richards · 2026-06-10 00:56 UTC · 0c9a5673811acc3900504540ec9902fe24492438 · parent 2c596008 · browse files
modifiedcrates/anvil-web/src/ui.rs+46 −17
| ⋯ 52 unchanged lines | |||
| 53 | 53 | table.code td.ln { text-align:right; color:var(--muted); user-select:none; width:1%; border-right:1px solid var(--border); background:var(--code-bg); } | |
| 54 | 54 | .clone { border:1px solid var(--border); border-radius:6px; padding:12px 16px; margin:16px 0; } | |
| 55 | 55 | .clone-head { display:flex; align-items:center; gap:12px; margin-bottom:8px; } | |
| 56 | - | .clone-tabs { display:flex; gap:4px; margin-left:auto; } | |
| 57 | - | .clone-tab { font-size:12px; padding:2px 10px; border:1px solid var(--border); border-radius:2em; background:var(--bg); color:var(--muted); cursor:pointer; } | |
| 58 | - | .clone-tab.active { background:var(--accent); color:#fff; border-color:var(--accent); } | |
| 56 | + | .clone-tabs { display:flex; margin-left:auto; } | |
| 57 | + | .clone-tab { font-size:12px; padding:2px 10px; border:1px solid var(--border); border-radius:0; margin-left:-1px; position:relative; background:var(--bg); color:var(--muted); cursor:pointer; } | |
| 58 | + | .clone-tab:first-child { border-radius:2em 0 0 2em; margin-left:0; } | |
| 59 | + | .clone-tab:last-child { border-radius:0 2em 2em 0; } | |
| 60 | + | .clone-tab:first-child:last-child { border-radius:2em; } | |
| 61 | + | .clone-tab.active { background:var(--accent); color:#fff; border-color:var(--accent); z-index:1; } | |
| 59 | 62 | .clone-cmd { display:flex; align-items:center; gap:8px; background:var(--code-bg); border:1px solid var(--border); border-radius:6px; padding:6px 10px; } | |
| 60 | 63 | .clone-cmd code { flex:1; font:12px ui-monospace,monospace; user-select:all; overflow-x:auto; white-space:nowrap; } | |
| 61 | 64 | .copy-btn { display:inline-flex; align-items:center; background:none; border:0; color:var(--muted); cursor:pointer; padding:2px; } | |
| ⋯ 18 unchanged lines | |||
| 80 | 83 | .linkbtn:hover { text-decoration:underline; } | |
| 81 | 84 | .btn { display:inline-block; background:var(--accent); color:#fff; border:1px solid var(--accent); border-radius:6px; padding:5px 12px; font-size:13px; cursor:pointer; } | |
| 82 | 85 | .btn:hover { text-decoration:none; opacity:.92; } | |
| 86 | + | .repo-nav { font-size:13px; } | |
| 87 | + | .repo-nav a { color:var(--muted); } | |
| 88 | + | .repo-nav a:hover { color:var(--accent); text-decoration:none; } | |
| 89 | + | .pill-group { display:inline-flex; } | |
| 90 | + | .pill-group > .pill { border-radius:0; margin-left:-1px; position:relative; } | |
| 91 | + | .pill-group > .pill:first-child { border-radius:2em 0 0 2em; margin-left:0; } | |
| 92 | + | .pill-group > .pill:last-child { border-radius:0 2em 2em 0; } | |
| 83 | 93 | form.stack p { margin:10px 0; } form.stack label { font-size:13px; color:var(--muted); } | |
| 84 | 94 | form.stack input[type=text], form.stack textarea { width:100%; max-width:480px; padding:6px 8px; border:1px solid var(--border); border-radius:6px; font:inherit; } | |
| 85 | 95 | form.stack .check { display:flex; gap:8px; align-items:flex-start; max-width:480px; } | |
| ⋯ 23 unchanged lines | |||
| 109 | 119 | .st.success { background:#dafbe1; color:#1a7f37; } .st.failure, .st.error { background:#ffebe9; color:#cf222e; } | |
| 110 | 120 | .log { background:#0d1117; color:#e6edf3; border-radius:6px; padding:14px 16px; overflow-x:auto; font:12px/1.5 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; white-space:pre-wrap; word-break:break-word; margin:0; } | |
| 111 | 121 | footer { color:var(--muted); font-size:12px; padding:24px 0; border-top:1px solid var(--border); margin-top:32px; } | |
| 122 | + | details.nav-menu { position:relative; } | |
| 123 | + | details.nav-menu > summary { list-style:none; cursor:pointer; color:var(--accent); font-size:14px; } | |
| 124 | + | details.nav-menu > summary::-webkit-details-marker { display:none; } | |
| 125 | + | details.nav-menu > summary::after { content:" ▾"; font-size:10px; color:var(--muted); } | |
| 126 | + | .nav-dropdown { position:absolute; right:0; top:calc(100% + 6px); background:var(--bg); border:1px solid var(--border); border-radius:6px; min-width:130px; box-shadow:0 4px 14px rgba(0,0,0,.1); z-index:200; padding:4px 0; } | |
| 127 | + | .nav-dropdown a, .nav-dropdown button { display:block; width:100%; padding:6px 14px; font-size:13px; color:var(--fg); text-align:left; background:none; border:0; cursor:pointer; font:inherit; text-decoration:none; } | |
| 128 | + | .nav-dropdown a:hover, .nav-dropdown button:hover { background:var(--code-bg); color:var(--fg); } | |
| 112 | 129 | "#; | |
| 113 | 130 | ||
| 114 | 131 | /// Clipboard icon for the clone "copy" button. | |
| ⋯ 11 unchanged lines | |||
| 126 | 143 | document.body.removeChild(ta); return Promise.resolve(); | |
| 127 | 144 | } | |
| 128 | 145 | document.addEventListener('click', function(e){ | |
| 146 | + | var nm=e.target.closest('details.nav-menu'); | |
| 147 | + | document.querySelectorAll('details.nav-menu').forEach(function(d){ if(d!==nm) d.removeAttribute('open'); }); | |
| 129 | 148 | var tab=e.target.closest('.clone-tab'); | |
| 130 | 149 | if(tab){ | |
| 131 | 150 | var box=tab.closest('.clone'), cmd=box.dataset[tab.dataset.proto]; | |
| ⋯ 70 unchanged lines | |||
| 202 | 221 | span style="margin-left:auto" { | |
| 203 | 222 | @match user { | |
| 204 | 223 | Some(u) => { | |
| 205 | - | a href="/-/settings" { (u.username) } | |
| 206 | - | " · " | |
| 207 | - | form method="post" action="/-/logout" style="display:inline" { | |
| 208 | - | button.linkbtn type="submit" { "sign out" } | |
| 224 | + | details.nav-menu { | |
| 225 | + | summary { (u.username) } | |
| 226 | + | div.nav-dropdown { | |
| 227 | + | a href="/-/settings" { "Settings" } | |
| 228 | + | form method="post" action="/-/logout" { | |
| 229 | + | button type="submit" { "Sign out" } | |
| 230 | + | } | |
| 231 | + | } | |
| 209 | 232 | } | |
| 210 | 233 | } | |
| 211 | 234 | None => { a href="/-/login" { "sign in" } } | |
| ⋯ 515 unchanged lines | |||
| 727 | 750 | a href=(format!("/{owner}")) { (owner) } " / " (repo) | |
| 728 | 751 | @if meta.is_private { " " span.pill { "private" } } | |
| 729 | 752 | } | |
| 730 | - | a.btn href=(format!("/{owner}/{repo}/ci")) { "CI" } | |
| 731 | - | a.btn href=(format!("/{owner}/{repo}/pages")) { "Pages" } | |
| 732 | - | @if can_write { | |
| 733 | - | a.btn href=(format!("/{owner}/{repo}/settings")) { "Settings" } | |
| 753 | + | span.repo-nav { | |
| 754 | + | a href=(format!("/{owner}/{repo}/ci")) { "CI" } | |
| 755 | + | " · " | |
| 756 | + | a href=(format!("/{owner}/{repo}/pages")) { "Pages" } | |
| 757 | + | @if can_write { | |
| 758 | + | " · " | |
| 759 | + | a href=(format!("/{owner}/{repo}/settings")) { "Settings" } | |
| 760 | + | } | |
| 734 | 761 | } | |
| 735 | 762 | } | |
| 736 | 763 | @if !meta.description.is_empty() { p.muted { (meta.description) } } | |
| ⋯ 136 unchanged lines | |||
| 873 | 900 | (breadcrumbs(&owner, &repo, &rev, &path, true)) | |
| 874 | 901 | @if markdown { | |
| 875 | 902 | p.view-toggle { | |
| 876 | - | @if rendered { | |
| 877 | - | span.pill.active { "Rendered" } " " | |
| 878 | - | a.pill href=(format!("{blob_url}?plain=1")) { "Source" } | |
| 879 | - | } @else { | |
| 880 | - | a.pill href=(blob_url) { "Rendered" } " " | |
| 881 | - | span.pill.active { "Source" } | |
| 903 | + | span.pill-group { | |
| 904 | + | @if rendered { | |
| 905 | + | span.pill.active { "Rendered" } | |
| 906 | + | a.pill href=(format!("{blob_url}?plain=1")) { "Source" } | |
| 907 | + | } @else { | |
| 908 | + | a.pill href=(blob_url) { "Rendered" } | |
| 909 | + | span.pill.active { "Source" } | |
| 910 | + | } | |
| 882 | 911 | } | |
| 883 | 912 | } | |
| 884 | 913 | } | |
| ⋯ 591 unchanged lines | |||