[WV2] Add search keyboard shortcuts
This commit is contained in:
parent
10e2140045
commit
b462272dc3
2 changed files with 62 additions and 0 deletions
61
app/assets/javascripts/wardrobe/item-search-keys.js
Normal file
61
app/assets/javascripts/wardrobe/item-search-keys.js
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/**
|
||||
* Keyboard shortcuts for item search.
|
||||
*
|
||||
* - Up/Down arrows move focus between the search field and the item list,
|
||||
* so keyboard users can quickly browse results without tabbing.
|
||||
* - Escape exits search mode (clicks the back button).
|
||||
*/
|
||||
document.addEventListener("keydown", (e) => {
|
||||
if (e.key === "Escape") {
|
||||
const backButton = document.querySelector(
|
||||
".item-search-form .back-button",
|
||||
);
|
||||
if (!backButton) return;
|
||||
|
||||
// Only act when focus is on the search input or a search result.
|
||||
const section = document.querySelector(".outfit-controls-section");
|
||||
const searchInput = section?.querySelector(
|
||||
'.search-form input[type="text"]',
|
||||
);
|
||||
const isSearchFocused =
|
||||
document.activeElement === searchInput ||
|
||||
document.activeElement?.closest(".search-results-list") != null;
|
||||
if (!isSearchFocused) return;
|
||||
|
||||
e.preventDefault();
|
||||
backButton.click();
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.key !== "ArrowDown" && e.key !== "ArrowUp") return;
|
||||
|
||||
const section = document.querySelector(".outfit-controls-section");
|
||||
if (!section) return;
|
||||
|
||||
const searchInput = section.querySelector('.search-form input[type="text"]');
|
||||
if (!searchInput) return;
|
||||
|
||||
// Collect all focusable item inputs in the results list.
|
||||
const itemInputs = [
|
||||
...section.querySelectorAll(
|
||||
'.search-results-list item-card input[type="checkbox"]',
|
||||
),
|
||||
];
|
||||
if (itemInputs.length === 0) return;
|
||||
|
||||
const allTargets = [searchInput, ...itemInputs];
|
||||
const currentIndex = allTargets.indexOf(document.activeElement);
|
||||
if (currentIndex === -1) return;
|
||||
|
||||
let nextIndex;
|
||||
if (e.key === "ArrowDown") {
|
||||
nextIndex = Math.min(currentIndex + 1, allTargets.length - 1);
|
||||
} else {
|
||||
nextIndex = Math.max(currentIndex - 1, 0);
|
||||
}
|
||||
|
||||
if (nextIndex !== currentIndex) {
|
||||
e.preventDefault();
|
||||
allTargets[nextIndex].focus();
|
||||
}
|
||||
});
|
||||
|
|
@ -18,6 +18,7 @@
|
|||
= javascript_include_tag "tab-panel", async: true
|
||||
= javascript_include_tag "outfit-rename-field", async: true
|
||||
= javascript_include_tag "wardrobe/item-card", async: true
|
||||
= javascript_include_tag "wardrobe/item-search-keys", async: true
|
||||
= javascript_include_tag "wardrobe/show", async: true
|
||||
= csrf_meta_tags
|
||||
%meta{name: 'outfit-viewer-morph-mode', value: 'full-page'}
|
||||
|
|
|
|||
Loading…
Reference in a new issue