mirror of
https://github.com/kennethreitz/kjvstudy.org.git
synced 2026-06-05 23:00:16 +00:00
Add keyboard navigation to books listing page
- ↑/↓ or j/k to select books - Enter to navigate to selected book - Click to select, click again to navigate - Visual highlight with green border for selected book 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,25 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.book-card.selected {
|
||||
border-color: #4a7c59;
|
||||
box-shadow: 0 0 0 2px rgba(74, 124, 89, 0.3);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.book-card.selected .book-name {
|
||||
color: #4a7c59;
|
||||
}
|
||||
|
||||
[data-theme="dark"] .book-card.selected {
|
||||
border-color: #6b9b7a;
|
||||
box-shadow: 0 0 0 2px rgba(107, 155, 122, 0.3);
|
||||
}
|
||||
|
||||
[data-theme="dark"] .book-card.selected .book-name {
|
||||
color: #6b9b7a;
|
||||
}
|
||||
|
||||
.book-name {
|
||||
font-size: 1.2rem;
|
||||
font-weight: 600;
|
||||
@@ -282,4 +301,61 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
const cards = document.querySelectorAll('.book-card');
|
||||
if (cards.length === 0) return;
|
||||
|
||||
let selectedIndex = -1;
|
||||
|
||||
function selectCard(index) {
|
||||
// Remove previous selection
|
||||
if (selectedIndex >= 0 && selectedIndex < cards.length) {
|
||||
cards[selectedIndex].classList.remove('selected');
|
||||
}
|
||||
|
||||
// Update index with bounds checking
|
||||
selectedIndex = Math.max(0, Math.min(index, cards.length - 1));
|
||||
|
||||
// Add selection to new card
|
||||
cards[selectedIndex].classList.add('selected');
|
||||
|
||||
// Scroll into view
|
||||
cards[selectedIndex].scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'center'
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('keydown', function(e) {
|
||||
// Don't handle if user is typing in an input
|
||||
if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
|
||||
|
||||
if (e.key === 'ArrowDown' || e.key === 'j') {
|
||||
e.preventDefault();
|
||||
selectCard(selectedIndex + 1);
|
||||
} else if (e.key === 'ArrowUp' || e.key === 'k') {
|
||||
e.preventDefault();
|
||||
selectCard(selectedIndex - 1);
|
||||
} else if (e.key === 'Enter' && selectedIndex >= 0) {
|
||||
e.preventDefault();
|
||||
window.location.href = cards[selectedIndex].href;
|
||||
}
|
||||
});
|
||||
|
||||
// Click to select
|
||||
cards.forEach((card, index) => {
|
||||
card.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
if (selectedIndex === index) {
|
||||
// Double-click behavior: navigate
|
||||
window.location.href = card.href;
|
||||
} else {
|
||||
selectCard(index);
|
||||
}
|
||||
});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user