Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add search-as-you-type (inline search results) feature #2093

Open
wants to merge 25 commits into
base: main
Choose a base branch
from

Conversation

kaycebasques
Copy link
Contributor

Fixes #1977

@choldgraf
Copy link
Collaborator

This is super cool

@12rambau
Copy link
Collaborator

12rambau commented Jan 7, 2025

For me it's the most wanted feature, brilliant !

Copy link
Collaborator

@drammock drammock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you a thousand times for including such clear and detailed code comments. So far I've only read the implementation, haven't played around with it on the PR build yet.

Comment on lines +353 to +356
// Don't interfere with the default search UX on /search.html.
if (window.location.pathname.endsWith("/search.html")) {
return;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should also account for dirhtml builds, which I think (?) will have a url like https://whatever.com/en/search/ or potentially https://whatever.com/en/search/index.html

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dirhtml was not on my radar. Will need to look into what that does to figure out how it affects the impl.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I introduced a temporary change to tox.ini in this PR to make docs-dev build dirhtml instead of html. It all seems to work fine still

// searchtools.js loads.
//
// Search class is defined in upstream Sphinx:
// https://github.com/sphinx-doc/sphinx/blob/master/sphinx/themes/basic/static/searchtools.js#L181
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

link to .../blob/master/... may suffer from line number drift or otherwise go stale. Let's use a permalink to a specific repo state.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SGTM

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed now, will let you resolve

}

// Create a new search-as-you-type results container.
results = document.createElement("section");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gabalafou would appreciate your perspective on what is the best node type for an appearing/disappearing list of search results, and how this can/should/will interact with things like tab focus.

tests/test_a11y.py Outdated Show resolved Hide resolved
Copy link

github-actions bot commented Jan 8, 2025

Coverage report

Click to see where and how coverage changed

FileStatementsMissingCoverageCoverage
(new stmts)
Lines missing
  src/pydata_sphinx_theme
  __init__.py
Project Total  

This report was generated by python-coverage-comment-action

tox.ini Outdated
@@ -122,7 +122,7 @@ set_env = PYDEVD_DISABLE_FILE_VALIDATION=1
extras = {[testenv:docs-no-checks]extras}
package = editable
commands =
sphinx-build -b html docs/ docs/_build/html -v -w warnings.txt {posargs}
sphinx-build -b dirhtml docs/ docs/_build/html -v -w warnings.txt {posargs}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be reverted before (hopefully eventually) merging

@kaycebasques
Copy link
Contributor Author

@drammock all actionable feedback addressed

@drammock
Copy link
Collaborator

drammock commented Jan 9, 2025

@drammock all actionable feedback addressed

time for more feedback then 😆 I was just playing around with the CI build, and 2 things didn't match expectations:

  1. pressing tab first focuses the entire search results container, seems more useful if the container wasn't a tab stop and the first tab went straight to the first search result link.
  2. pressing esc when tab-focus is on a search result doesn't exit the search modal/overlay.

@kaycebasques
Copy link
Contributor Author

time for more feedback then 😆

BRING IT

Will add inline code comments addressing the two latest items

@@ -261,6 +261,7 @@ var addEventListenerForSearchKeyboard = () => {
// also allow Escape key to hide (but not show) the dynamic search field
else if (document.activeElement === input && /Escape/i.test(event.key)) {
toggleSearchField();
resetSearchAsYouTypeResults();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the user types a query into the search box and then presses Esc to close the modal, then the last inline search results should be removed.

results.classList.add("empty");
// Remove the container element from the tab order. Individual search
// results are still focusable.
results.tabIndex = -1;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Attempting to make the search results container non-focusable here

// Check every link every time because the timing of when new results are
// added is unpredictable and it's not an expensive operation.
links.forEach((link) => {
link.tabIndex = 0; // Use natural tab order for search results.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Attempting to make sure that inline search results links are focusable here



@pytest.mark.a11y
def test_search_as_you_type(page: Page, url_base: str) -> None:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@drammock re: the search results container itself receiving focus, it seems like this test should have failed? Does CI not run the a11y tests on different OS / browser permutations?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, seems it should have 🤷🏻
CI only runs a11y tests in one job (ubuntu-latest, py3.12).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added #2095 to track the issue. I assume we'll want to address that in a separate PR

// When focus is on a search result, make sure that pressing Escape closes
// the search modal.
results.addEventListener("keydown", (event) => {
if (event.key === "Escape") {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Escape should work as expected now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Search-as-you-type UX built on top of built-in Sphinx search tools
4 participants