Skip to content

Fix search override #208

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

Merged
merged 6 commits into from
Apr 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

from __future__ import annotations

import os
import re
from typing import TYPE_CHECKING
from pathlib import PurePosixPath
Expand All @@ -25,7 +24,6 @@
"sphinx.ext.autosummary",
"scanpydoc",
"sphinx.ext.linkcode", # needs to be after scanpydoc
"sphinx_search.extension",
]

intersphinx_mapping = dict(
Expand Down Expand Up @@ -77,12 +75,6 @@ def test_search(value: str, pattern: str) -> bool:

rtd_links_prefix = PurePosixPath("src")

# PR versions don’t have a own search index
if re.fullmatch(r"\d+", os.environ.get("READTHEDOCS_VERSION", "")):
rtd_sphinx_search_default_filter = (
f"subprojects:{os.getenv('READTHEDOCS_PROJECT')}/latest"
)


def setup(app: Sphinx) -> None:
"""Set up custom Sphinx extension."""
Expand Down
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ test = [
doc = [
'scanpydoc[typehints,myst,theme]',
'sphinx',
'readthedocs-sphinx-search',
]
typehints = ['sphinx-autodoc-typehints>=1.15.2']
theme = ['sphinx-book-theme>=1.1.0']
Expand Down
4 changes: 1 addition & 3 deletions src/scanpydoc/theme/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@

from __future__ import annotations

import os
from typing import TYPE_CHECKING
from pathlib import Path

Expand All @@ -90,7 +89,6 @@ def setup(app: Sphinx) -> dict[str, bool]: # pragma: no cover
app.add_html_theme("scanpydoc", str(HERE))

# if we’re on ReadTheDocs, hide the pydata-sphinx-theme search popup
if os.environ.get("READTHEDOCS_VERSION", ""): # pragma: no cover
app.add_js_file("scripts/rtd-sphinx-search.js", loading_method="defer")
app.add_js_file("scripts/rtd-sphinx-search.js", loading_method="defer")

return dict(parallel_read_safe=True, parallel_write_safe=True)
3 changes: 2 additions & 1 deletion src/scanpydoc/theme/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@
{% endif %}
{%- endblock -%}

<!-- Styles that come last -->
<!-- Styles that come last and meta tags -->
{%- block extrahead -%}
{{ super() }}
<meta name="readthedocs-addons-api-version" content="1" />
{% if theme_accent_color %}
<!-- prettier-ignore-start -->
<style>
Expand Down
70 changes: 40 additions & 30 deletions src/scanpydoc/theme/static/scripts/rtd-sphinx-search.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,47 @@
/**
* This JS is only included when the RTD Sphinx search is active.
* See https://docs.readthedocs.com/platform/stable/addons.html#integrate-with-search-as-you-type
*/

// wire up the search key combination
addEventListener(
"keydown",
({ key, metaKey, ctrlKey }) => {
if (key === "k" && (metaKey || ctrlKey)) {
if (isModalVisible()) {
removeSearchModal()
} else {
showSearchModal()
document.addEventListener("readthedocs-addons-data-ready", (event) => {
const { addons } = event.detail.data()
if (!addons.search?.enabled) {
return
}

// wire up the search key combination
addEventListener(
"keydown",
({ key, metaKey, ctrlKey }) => {
if (key === "k" && (metaKey || ctrlKey)) {
const here = document.querySelector("readthedocs-search")?.show
const event = new CustomEvent(
`readthedocs-search-${here ? "hide" : "show"}`,
)
document.dispatchEvent(event)
}
}
},
{ passive: true },
)
},
{ passive: true },
)

// start attempting to override the search popup and to wire up the search button
setTimeout(overrideSearch, 0)
// start attempting to override the search popup and to wire up the search button
setTimeout(overrideSearch, 0)

function overrideSearch() {
/** @type {HTMLDivElement} */
const theme_popup = document.querySelector(".search-button__wrapper")
/** @type {HTMLButtonElement} */
const search_button = document.querySelector("button[aria-label='Search']")
if (!theme_popup || !search_button) {
// try again later
setTimeout(overrideSearch, 500)
return
function overrideSearch() {
/** @type {HTMLDivElement} */
const theme_popup = document.querySelector(".search-button__wrapper")
/** @type {HTMLButtonElement} */
const search_button = document.querySelector("button[aria-label='Search']")
if (!theme_popup || !search_button) {
// try again later
setTimeout(overrideSearch, 500)
return
}
// Hide the pydata theme’s search popup.
theme_popup.style.display = "none"
// wire up the search button
search_button.addEventListener("click", () => {
const event = new CustomEvent("readthedocs-search-show")
document.dispatchEvent(event)
})
}
// Hide the pydata theme’s search popup.
theme_popup.style.display = "none"
// wire up the search button
search_button.addEventListener("click", () => showSearchModal())
}
})
86 changes: 19 additions & 67 deletions src/scanpydoc/theme/static/styles/scanpy.css
Original file line number Diff line number Diff line change
Expand Up @@ -31,71 +31,23 @@ dl.citation > dt {
outline: 2px solid var(--pst-color-link-hover);
}

/* Make the readthedocs-sphinx-search popup adapt to the theme */
/*backdrop*/
html[data-theme] .search__backdrop {
z-index: 1020;
backdrop-filter: saturate(150%) blur(20px);
}
/*container*/
html[data-theme] :is(.search__outer, .rtd__search__credits) {
font-family: var(--pst-font-family-base);
color: var(--pst-color-text-base);
background-color: var(--pst-color-background);
border-color: var(--pst-color-border);
}
html[data-theme] .search__outer {
border-top-left-radius: var(--bs-border-radius);
border-top-right-radius: var(--bs-border-radius);
}
html[data-theme] .rtd__search__credits {
border-bottom-left-radius: var(--bs-border-radius);
border-bottom-right-radius: var(--bs-border-radius);
}
html[data-theme] .rtd__search__credits a {
color: var(--pst-color-link);
}
/*icons*/
html[data-theme] .search__outer::before {
/* this can’t be put on .search__outer__input, as <input/> supports no ::before */
position: absolute;
padding: 0.4em 0.3em;
content: "\f002"; /* fa-magnifying-glass */
font: var(--fa-font-solid);
color: var(--pst-color-text-muted);
}
html[data-theme] .search__cross__img polygon {
fill: currentcolor;
}
/*input*/
html[data-theme] .search__outer__input {
color: var(--pst-color-text-base);
background-image: none; /* hide the default search icon */
background-color: transparent;
border-bottom-color: var(--pst-color-border);
}
html[data-theme] .search__outer .bar::before,
html[data-theme] .search__outer .bar::after {
background-color: var(--pst-color-accent);
}
/*results*/
html[data-theme] :is(.search__result__subheading span, .search__result__single) {
border-bottom-color: var(--pst-color-border);
}
html[data-theme] .search__result__single:last-of-type {
border-bottom-width: 0;
}
html[data-theme] :is(.outer_div_page_results:hover, .search__result__box .active) {
background-color: var(--pst-color-accent-bg);
}
html[data-theme]
:is(.search__error__box, .search__result__subheading, .search__result__content) {
color: var(--pst-color-text-base);
}
html[data-theme]
.search__outer
:is(.search__result__content, .search__result__title)
span {
border-bottom-color: var(--pst-color-border);
background-color: var(--pst-color-target);
/* Make the readthedocs search popup adapt to the theme.
* Might break again soon: https://github.com/readthedocs/addons/issues/570
*/
:root {
--readthedocs-search-backdrop-color: var(--pst-color-shadow);
--readthedocs-search-color: var(--pst-color-text-base);
--readthedocs-search-content-background-color: var(--pst-color-background);
--readthedocs-search-content-border-color: var(--pst-color-border);
--readthedocs-search-filters-border-color: var(--pst-color-border);
--readthedocs-search-font-family: var(--pst-font-family-base);
--readthedocs-search-font-size: var(--pst-font-size-base);
--readthedocs-search-footer-background-color: var(--pst-color-on-background);
--readthedocs-search-footer-code-background-color: var(--pst-color-surface);
--readthedocs-search-footer-code-border-color: var(--pst-color-border);
--readthedocs-search-input-background-color: var(--pst-color-surface);
--readthedocs-search-result-section-border-color: var(--pst-color-border);
--readthedocs-search-result-section-color: var(--pst-color-link);
--readthedocs-search-result-section-highlight-color: var(--pst-color-accent);
--readthedocs-search-result-section-subheading-color: var(--pst-color-text-muted);
}