Improve suggestions accessibility and search privacy

This commit is contained in:
Ted Pier 2026-07-11 15:27:36 -07:00
parent abe4c6e7bc
commit 6f9242d20e
3 changed files with 21 additions and 12 deletions

View File

@ -541,7 +541,7 @@ span > select {
.light-theme .pure-button-primary:focus,
.light-theme .pure-button-secondary:hover,
.light-theme .pure-button-secondary:focus,
.light-theme .active {
.light-theme #suggestions .active {
color: #fff !important;
border-color: rgba(0, 182, 240, 0.75) !important;
background-color: rgba(0, 182, 240, 0.75) !important;
@ -589,7 +589,7 @@ span > select {
.no-theme .pure-button-primary:focus,
.no-theme .pure-button-secondary:hover,
.no-theme .pure-button-secondary:focus,
.no-theme .active {
.no-theme #suggestions .active {
color: #fff !important;
border-color: rgba(0, 182, 240, 0.75) !important;
background-color: rgba(0, 182, 240, 0.75) !important;
@ -650,7 +650,7 @@ span > select {
.dark-theme .pure-button-primary:focus,
.dark-theme .pure-button-secondary:hover,
.dark-theme .pure-button-secondary:focus,
.dark-theme .active {
.dark-theme #suggestions .active {
color: #fff !important;
border-color: rgb(0, 182, 240) !important;
background-color: rgba(0, 182, 240, 1) !important;
@ -713,7 +713,7 @@ body.dark-theme {
.no-theme .pure-button-primary:focus,
.no-theme .pure-button-secondary:hover,
.no-theme .pure-button-secondary:focus,
.no-theme .active {
.no-theme #suggestions .active {
color: #fff !important;
border-color: rgb(0, 182, 240) !important;
background-color: rgba(0, 182, 240, 1) !important;
@ -943,6 +943,7 @@ h1, h2, h3, h4, h5, p,
border: 1px solid #a0a0a0;
z-index: 200;
padding: .25em 0;
margin: 0;
display: none;
}

View File

@ -50,19 +50,24 @@ searchbox?.addEventListener("input", function () {
);
const body = await resp.json();
// As a sanity check, ensure the
// suggestions match the query.
if (body.query != searchbox.value) {
return;
}
// Put the results into DOM.
resetSuggestions();
const results = body.suggestions;
for (let i = 0; i < results.length; i++) {
const s = document.createElement("a");
s.href = `/search?q=${encodeURIComponent(results[i])}`;
s.href = "/search";
s.innerText = results[i];
s.setAttribute("role", "option");
s.setAttribute("aria-selected", "false");
s.addEventListener("click", function (e) {
searchbox.value = results[i];
if (searchbox.form?.requestSubmit) {
searchbox.form.requestSubmit();
} else {
searchbox.form?.submit();
}
e.preventDefault();
});
suggestions.appendChild(s);
}
} catch (err) {
@ -109,8 +114,10 @@ searchbox?.addEventListener("keydown", function (e) {
for (let i = 0; i < currentSuggestions.length; i++) {
if (i == selectedSuggestion) {
currentSuggestions[i].classList.add("active");
currentSuggestions[i].setAttribute("aria-selected", "true");
} else if (currentSuggestions[i].classList.contains("active")) {
currentSuggestions[i].classList.remove("active");
currentSuggestions[i].setAttribute("aria-selected", "false");
}
}
});

View File

@ -9,11 +9,12 @@
<% end %>
<fieldset id="search-container">
<input type="search" id="searchbox" autocorrect="off"
aria-autocomplete="list" aria-controls="suggestions"
autocapitalize="none" spellcheck="false" <% if autofocus %>autofocus<% end %>
name="q" placeholder="<%= I18n.translate(locale, "search") %>"
title="<%= I18n.translate(locale, "search") %>"
value="<%= env.get?("search").try {|x| HTML.escape(x.as(String)) } %>">
<div id="suggestions"></div>
<ul id="suggestions"></ul>
</fieldset>
<button type="submit" id="searchbutton" aria-label="<%= I18n.translate(locale, "search") %>">
<i class="icon ion-ios-search"></i>