Skip to content

Commit 3473c3f

Browse files
Timeline: Fix styling of benchmark list and add search
1 parent 89a709d commit 3473c3f

2 files changed

Lines changed: 90 additions & 0 deletions

File tree

‎codespeed/static/css/timeline.css‎

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,53 @@
11
select#baseline {
22
width: 100%;
33
}
4+
5+
/* Benchmark picker: a search box over a list that scrolls inside its card */
6+
div#benchmarksearchbox { position: relative; margin: 0.2em 0 0.6em; }
7+
div#benchmarksearchbox::before {
8+
/* Bootstrap Icons search (MIT, twbs/icons), coloured via mask */
9+
content: '';
10+
position: absolute;
11+
left: 0.55em;
12+
top: 50%;
13+
width: 0.85em;
14+
height: 0.85em;
15+
transform: translateY(-50%);
16+
background-color: var(--text-faint);
17+
-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001q.044.06.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1 1 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0'/%3E%3C/svg%3E") no-repeat center / contain;
18+
mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001q.044.06.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1 1 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0'/%3E%3C/svg%3E") no-repeat center / contain;
19+
pointer-events: none;
20+
}
21+
div#benchmarksearchbox:focus-within::before { background-color: var(--text-muted); }
22+
input#benchmarksearch {
23+
display: block;
24+
box-sizing: border-box;
25+
width: 100%;
26+
margin: 0;
27+
font: inherit;
28+
font-size: 0.93em;
29+
color: var(--text);
30+
padding: 0.25em 0.5em 0.25em 1.8em;
31+
background-color: var(--surface);
32+
border: 1px solid var(--border-strong);
33+
border-radius: var(--radius-sm);
34+
}
35+
div#benchmarklist {
36+
max-height: min(60vh, 34em);
37+
overflow-y: auto;
38+
overscroll-behavior: contain;
39+
/* let the scrollbar sit in the card's padding rather than over the names */
40+
margin-right: -0.6em;
41+
padding-right: 0.3em;
42+
}
43+
div#benchmarklist ul:last-of-type { margin-bottom: 0; }
44+
/* Radio and name side by side, so a long name wraps under itself instead of
45+
dropping below the radio and running out of the card */
46+
div#benchmark li { display: flex; align-items: flex-start; gap: 0.4em; }
47+
div#benchmark li input { flex: none; margin-top: 0.25em; }
48+
div#benchmark li label { min-width: 0; overflow-wrap: anywhere; }
49+
/* While searching, matches show even in folded suites */
50+
div#benchmarklist.searching li { display: flex !important; }
51+
div#benchmarklist.searching li.nomatch,
52+
div#benchmarklist.searching ul.nomatch { display: none !important; }
53+
p#benchmarknomatch { margin: 0.2em 0; color: var(--text-muted); }

‎codespeed/static/js/timeline.js‎

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,10 +651,50 @@ function updateEnvIndicators() {
651651
});
652652
}
653653

654+
function initBenchmarkSearch() {
655+
var list = $("#benchmarklist");
656+
var search = $("#benchmarksearch");
657+
var groups = list.children("ul");
658+
659+
search.on("input", function() {
660+
var terms = $(this).val().toLowerCase().split(/\s+/).filter(Boolean);
661+
var anyMatch = false;
662+
groups.each(function() {
663+
var groupMatch = false;
664+
$(this).children("li").each(function() {
665+
var name = $(this).children("label").text().toLowerCase();
666+
var match = terms.every(function(t) { return name.indexOf(t) !== -1; });
667+
$(this).toggleClass("nomatch", !match);
668+
groupMatch = groupMatch || match;
669+
});
670+
$(this).toggleClass("nomatch", !groupMatch);
671+
anyMatch = anyMatch || groupMatch;
672+
});
673+
list.toggleClass("searching", terms.length > 0);
674+
$("#benchmarknomatch").prop("hidden", anyMatch);
675+
list.scrollTop(0);
676+
}).on("keydown", function(e) {
677+
if (e.key === "Enter") {
678+
// pick the first match
679+
list.find("li:not(.nomatch) input").first().prop("checked", true).change();
680+
} else if (e.key === "Escape" && $(this).val()) {
681+
$(this).val("").trigger("input");
682+
}
683+
});
684+
685+
// bring the selected benchmark into view inside the scrolling list
686+
var checked = list.find("input:checked").closest("li");
687+
if (checked.length) {
688+
list.scrollTop(checked.position().top - list.children().first().position().top -
689+
list.height() / 2);
690+
}
691+
}
692+
654693
function initializeSite() {
655694
var params = getUrlParams();
656695
setExeColors();
657696
setValuesOfInputFields(params);
697+
initBenchmarkSearch();
658698

659699
var onChange = function() { updateUrl(); refreshContent(); };
660700

0 commit comments

Comments
 (0)